00001 #include <cassert>
00002 #include <sstream>
00003
00004
00005 #include <TStyle.h>
00006 #include <TColor.h>
00007 #include <TROOT.h>
00008 #include <TH1F.h>
00009 #include <TEnv.h>
00010 #include <TVirtualX.h>
00011 #include <TGeoManager.h>
00012
00013 #include "TridPageDisplay.h"
00014 #include "TridPage.h"
00015 #include "TridGLFrame.h"
00016 #include "TridFlatGLFrame.h"
00017 #include "TridStereoGLFrame.h"
00018 #include "TridAnaglyphGLFrame.h"
00019 #include "TridSketches.h"
00020 #include "TridControl.h"
00021 #include "SelectionInfoPage.h"
00022
00023
00024 #include "Midad/Base/PageProxy.h"
00025 #include "Midad/Gui/GuiBox.h"
00026 #include "Midad/Gui/GuiCanvas.h"
00027 #include "Midad/Gui/GuiMainWindow.h"
00028 #include "Midad/Gui/GuiMenu.h"
00029 #include "Midad/Base/Mint.h"
00030 #include "Midad/Base/PageDisplay.h"
00031
00032
00033
00034 #include <sigc++/sigc++.h>
00035 #include <sigc++/class_slot.h>
00036
00037
00038 #include <DataUtil/GetCandidate.h>
00039 #include <JobControl/JobC.h>
00040 #include "MessageService/MsgService.h"
00041 #include "MinosObjectMap/MomNavigator.h"
00042 #include "Plex/PlexHandle.h"
00043 #include "Plex/PlexSEIdAltL.h"
00044 #include "Plex/PlexStripEndId.h"
00045 #include "DataUtil/GetVldContext.h"
00046
00047 CVSID("$Id: TridPage.cxx,v 1.48 2007/08/27 20:31:25 tagg Exp $");
00048
00049 using namespace SigC;
00050
00051
00052
00053 TridPage::TridPage()
00054 : fWindowName("Unnamed"),
00055 fGLFrame(0),
00056 fGuiBox(0),
00057 fMainWindow(0),
00058 fFileMenu(0),
00059 fOptionsMenu(0),
00060 fTridControl(0),
00061 fAutoPOV(0,0,0,10,45,25),
00062 fFullPOV(0,0,0,10,45,25),
00063 fMint(0),
00064 fPageDisplay(0),
00065 fModels(),
00066 fColorHistogram(0),
00067 fTransHistogram(0),
00068 fViewMode(kViewNone),
00069 fCreateHistograms(true),
00070 fViewModesSupported( kView2D | kView3D | kViewStereo | kViewCrossEyed | kViewRedBlue | kViewBlueRed )
00071 {
00072
00073 fViewMode = kView3D;
00074 }
00075
00076 TridPage::TridPage(TridPage& otherPage)
00077 : PageABC( otherPage ),
00078 TObject( otherPage ),
00079 fWindowName("Unnamed"),
00080 fGLFrame(0),
00081 fGuiBox(0),
00082 fMainWindow(0),
00083 fFileMenu(0),
00084 fOptionsMenu(0),
00085 fTridControl(0),
00086 fAutoPOV(0,0,0,10,45,25),
00087 fFullPOV(0,0,0,10,45,25),
00088 fMint(0),
00089 fPageDisplay(0),
00090 fModels(),
00091 fColorHistogram(0),
00092 fTransHistogram(0),
00093 fViewMode(kViewNone),
00094 fCreateHistograms(true),
00095 fViewModesSupported( kView2D | kView3D | kViewStereo | kViewCrossEyed )
00096 {
00097 MSG("TriD",Msg::kFatal) << "Trid Copy Constructor used.. please don't." << endl;
00098 }
00099
00100 TridPage::~TridPage()
00101 {
00102 MSG("TriD",Msg::kDebug) << "Destructor called" << endl;
00103
00104 fModels.Clear();
00105
00106
00107
00108
00109 fTridControl->DisconnectTridPage(this);
00110 }
00111
00112 TObject* TridPage::Init(Mint* mint, PageDisplay* pd, GuiBox& box)
00113 {
00114
00115 MSG("TriD",Msg::kDebug) << "TridPage: Init()" << endl;
00116
00117 fMint = mint;
00118 fPageDisplay = pd;
00119
00120 fMenuBar = manage(new GuiMenuBar(box));
00121 box.Add(*fMenuBar);
00122
00123 fFileMenu = manage(new GuiMenu);
00124 fMenuBar->AddMenu(*fFileMenu,"File");
00125
00126 fOptionsMenu = manage(new GuiMenu);
00127 fMenuBar->AddMenu(*fOptionsMenu,"Options");
00128
00129 fGuiBox = manage(new GuiBox(box,kVerticalFrame,100,100));
00130 box.Add(*fGuiBox);
00131 box.Show(*fGuiBox);
00132 fMainWindow = dynamic_cast<TGWindow*>(&box);
00133 assert(fMainWindow);
00134
00135
00136
00137 fTridControl = TridControl::Instance(pd);
00138 assert(fTridControl);
00139 fTridControl->ConnectTridPage(this);
00140
00141
00142 if(fCreateHistograms) {
00143 char buff[100];
00144 sprintf(buff,"%s_Color",fWindowName.Data());
00145 fColorHistogram = new TH1F(buff,buff,50,0,1);
00146 sprintf(buff,"%s_Trans",fWindowName.Data());
00147 fTransHistogram = new TH1F(buff,buff,50,0,1);
00148 fTridControl->AddHistograms(fWindowName.Data(),fColorHistogram,fTransHistogram);
00149 }
00150
00151
00152
00153 GuiMenu::GuiMenuList::iterator mit;
00154 mit = fFileMenu->Add("Print");
00155 (*mit)->Connect(slot_class(*this,&TridPage::Print));
00156
00157
00158
00159 MSG("TriD",Msg::kDebug)<< "Supported modes: " << fViewModesSupported << endl;
00160 if(fViewModesSupported >0) {
00161 GuiMenu* viewmenu = manage(new GuiMenu);
00162 fOptionsMenu->Add("View",*viewmenu);
00163
00164 if(fViewModesSupported & kView2D) {
00165 mit = viewmenu->Add("2D View (Orthographic)");
00166 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridPage::ViewMenuHandler),
00167 kView2D) ,mit) ,viewmenu));
00168 if(fViewMode == kView2D) viewmenu->CheckEntry(mit);
00169 }
00170
00171 if(fViewModesSupported & kView3D) {
00172 mit = viewmenu->Add("3D View");
00173 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridPage::ViewMenuHandler),
00174 kView3D) ,mit) ,viewmenu));
00175 if(fViewMode == kView3D) viewmenu->CheckEntry(mit);
00176 }
00177
00178 if(fViewModesSupported & kViewStereo) {
00179 mit = viewmenu->Add("Stereoscopic");
00180 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridPage::ViewMenuHandler),
00181 kViewStereo) ,mit) ,viewmenu));
00182 if(fViewMode == kViewStereo) viewmenu->CheckEntry(mit);
00183 }
00184
00185 if(fViewModesSupported & kViewCrossEyed) {
00186 mit = viewmenu->Add("Cross-Eyed");
00187 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridPage::ViewMenuHandler),
00188 kViewCrossEyed) ,mit) ,viewmenu));
00189 if(fViewMode == kViewCrossEyed) viewmenu->CheckEntry(mit);
00190 }
00191
00192 if(fViewModesSupported & kViewRedBlue) {
00193 mit = viewmenu->Add("Red-Blue Glasses");
00194 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridPage::ViewMenuHandler),
00195 kViewRedBlue) ,mit) ,viewmenu));
00196 if(fViewMode == kViewRedBlue) viewmenu->CheckEntry(mit);
00197 }
00198
00199 if(fViewModesSupported & kViewBlueRed) {
00200 mit = viewmenu->Add("Blue-Red Glasses");
00201 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridPage::ViewMenuHandler),
00202 kViewBlueRed) ,mit) ,viewmenu));
00203 if(fViewMode == kViewBlueRed) viewmenu->CheckEntry(mit);
00204 }
00205 }
00206
00207 SetupFrame( fViewMode );
00208 return this;
00209 }
00210
00211 void TridPage::ViewMenuHandler(GuiMenu* menu, GuiMenu::GuiMenuList::iterator mit,
00212 TridPage::ViewMode_t mode)
00213 {
00214 GuiMenu::GuiMenuList& mlist = menu->GetMenuList();
00215 GuiMenu::GuiMenuList::iterator it, done = mlist.end();
00216 for (it = mlist.begin(); it != done; ++it)
00217 menu->CheckEntry(it,false);
00218 menu->CheckEntry(mit,true);
00219 if(fViewMode!=mode)
00220 SetupFrame(mode);
00221 }
00222
00223
00224 void TridPage::SetupFrame( TridPage::ViewMode_t mode )
00225 {
00226
00227 TridSketchList oldList;
00228 TridPOV oldPOV;
00229
00230 if(fGLFrame) {
00231 oldList.AddSketchList(*fGLFrame);
00232 TridSketchListItr itr = oldList.GetIterator();
00233 TridSketch* sketch;
00234 while( (sketch = itr.Next()) ){
00235 sketch->SetDirty();
00236 }
00237
00238 oldPOV.Copy(fGLFrame->fPOV);
00239 fGLFrame->ClearSketches();
00240 fGuiBox->Remove(*fGLFrame);
00241 fGLFrame = 0;
00242
00243
00244 }
00245
00246 fViewMode = mode;
00247 fGLFrame = SigC::manage(CreateNewGLFrame(fViewMode));
00248 fGuiBox->Add(*fGLFrame);
00249 fGuiBox->Show(*fGLFrame);
00250 fPageDisplay->UpdateGui();
00251
00252 fGLFrame->AddSketchList(oldList);
00253 fGLFrame->fPOV.Copy(oldPOV);
00254
00255
00256 fGLFrame->SetupProjection();
00257 fGLFrame->SetPOV(fFullPOV);
00258 fGLFrame->Update();
00259
00260 }
00261
00262 TridGLFrame* TridPage::CreateNewGLFrame( TridPage::ViewMode_t mode )
00263 {
00264 if(mode==kView2D) {
00265 MSG("TriD",Msg::kDebug) << "Changing to 2D" << endl;
00266 return new TridFlatGLFrame(this,*fGuiBox,fTridControl);
00267 }
00268 if ( mode == kViewStereo) {
00269 MSG("TriD",Msg::kDebug) << "Changing to Stereoscopic" << endl;
00270 return new TridStereoGLFrame(this,*fGuiBox,fTridControl,-1);
00271 }
00272 if ( mode == kViewCrossEyed) {
00273 MSG("TriD",Msg::kDebug) << "Changing to Crosseyed" << endl;
00274 return new TridStereoGLFrame(this,*fGuiBox,fTridControl,1);
00275 }
00276 if ( mode == kViewRedBlue) {
00277 MSG("TriD",Msg::kDebug) << "Changing to Red/Blue glasses mode" << endl;
00278 return new TridAnaglyphGLFrame(this,*fGuiBox,fTridControl,-1);
00279 }
00280 if ( mode == kViewBlueRed) {
00281 MSG("TriD",Msg::kDebug) << "Changing to Blue/Red glasses mode" << endl;
00282 return new TridAnaglyphGLFrame(this,*fGuiBox,fTridControl,1);
00283 }
00284
00285
00286 MSG("TriD",Msg::kDebug) << "Changing to 3D" << endl;
00287 return new TridGLFrame(this,*fGuiBox,fTridControl);
00288 }
00289
00290
00291
00292 TVector3 TridPage::GetColor( Float_t x )
00293 {
00294
00295 int n = gStyle->GetNumberOfColors();
00296 int index = (int)(x*(float)n);
00297 if(index>=n) index = n-1;
00298 if(index<0) index = 0;
00299 int colNum = gStyle->GetColorPalette(index);
00300 TColor* colref = gROOT->GetColor(colNum);
00301 TVector3 rgb(colref->GetRed(),colref->GetGreen(),colref->GetBlue());
00302 return rgb;
00303 }
00304
00305
00306 void TridPage::Update()
00307 {
00308 MSG("TriD",Msg::kDebug) << "TridPage::Update()" << endl;
00309 assert(fMint);
00310
00311
00312 std::vector<VldContext> contexts = DataUtil::GetVldContext(&(fMint->GetJobC().Mom));
00313 if(contexts.size() ==0 ) {
00314 MSG("TriD",Msg::kError) << "No VldContext of any kind in Mom. Have you loaded a valid data file?" << std:: endl;
00315 return;
00316 }
00317 fContext = contexts[0];
00318
00319 fTridControl->ClearPicked();
00320 fTridControl->ClearSelected();
00321
00322
00323 double tmin = -2*Munits::microsecond;
00324 double tmax = tmin + 15*Munits::microsecond;
00325
00326 if(fContext.GetDetector()==Detector::kFar) {
00327 tmin = 0;
00328 tmax = 100*Munits::microsecond;
00329 }
00330 fTridControl->GetAnimator().SetTimeRange(tmin,tmax);
00331
00332 fModels.Clear();
00333 CreateModels();
00334
00335 fGLFrame->DeleteSketches();
00336 CreateSketches();
00337 CreateScenery();
00338
00339 fGLFrame->Update();
00340 }
00341
00342 void TridPage::Clear()
00343 {
00344 MSG("TriD",Msg::kDebug) << "TridPage::Clear()" << endl;
00345 fModels.Clear();
00346 if(fGLFrame) fGLFrame->DeleteSketches();
00347 }
00348
00349 void TridPage::CreateModels()
00350 {
00351 }
00352
00353 void TridPage::CreateSketches()
00354 {
00355 }
00356
00357
00358 void TridPage::CreateScenery()
00359 {
00360 }
00361
00362 void TridPage::ModifySketches()
00363 {
00364
00365
00366
00367 fColorHistogram->Reset();
00368 fTransHistogram->Reset();
00369
00370 int nsketches =0;
00371
00372 TridSketchListItr itr = fGLFrame->GetIterator();
00373 while( TridSketch* sketch = itr.Next() ) {
00374 int sketchnum = sketch->GetId();
00375 TridModel* model = fModels.GetModelFromSketch(sketchnum);
00376
00377 if((sketch)&&(model)) {
00378 nsketches++;
00379
00380
00381 Double_t color_x = fTridControl->GetRangedModelColor(model);
00382 Double_t trans_x = fTridControl->GetRangedModelTrans(model);
00383
00384
00385 sketch->SetColor(fTridControl->GetColor(color_x));
00386 sketch->SetTransparency(trans_x);
00387
00388
00389 sketch->SetDrawn(true);
00390 if(color_x<0)
00391 if(!fTridControl->ShowColorUnderScale())
00392 sketch->SetDrawn(false);
00393
00394 if(color_x>1)
00395 if(!fTridControl->ShowColorOverScale())
00396 sketch->SetDrawn(false);
00397
00398
00399 if(fTridControl->IsPicked(model))
00400 sketch->SetColor(1,1,1);
00401
00402
00403 if(fTridControl->IsSelected(model))
00404 sketch->SetColor(1,1,1);
00405
00406
00407 fColorHistogram->Fill(color_x);
00408 fTransHistogram->Fill(trans_x);
00409 } else {
00410 MSG("TriD",Msg::kError) << "Cannot find sketch or model, model number " << model
00411 << " ModelAdd: " << model
00412 << " SketchNumber: " << sketchnum
00413 << " SketchAddr: " << sketch << endl;
00414 }
00415 }
00416 }
00417
00418 void TridPage::MouseOver(int sketchname)
00419 {
00420 static int lastmouseover;
00421 if(sketchname!=lastmouseover) {
00422
00423 SelectionInfoPage* selInfo = fTridControl->GetSelectionInfoPage();
00424 TridModel* model = fModels.GetModelFromSketch(sketchname);
00425
00426 fTridControl->ClearPicked();
00427 if(model) {
00428
00429 fTridControl->SetPicked(model);
00430 stringstream oss;
00431 model->Print(oss);
00432 std::string s = oss.str();
00433 if(selInfo) selInfo->SetText(s);
00434 }
00435 fTridControl->ChangePicked();
00436 }
00437 lastmouseover = sketchname;
00438 }
00439
00440 void TridPage::MouseClick(int sketchname)
00441 {
00442 TridModel* model = fModels.GetModelFromSketch(sketchname);
00443 if(model) {
00444 fTridControl->ToggleSelected(model);
00445 fTridControl->ChangeSelected();
00446 }
00447 }
00448
00449 void TridPage::Print()
00450 {
00451 this->PrintToFile(Form("snapshot_%s.png",fWindowName.Data()));
00452 }
00453
00454 void TridPage::PrintToFile(const char* filename, const char* text)
00455 {
00456 fGLFrame->Print(filename, text);
00457 }
00458
00459 void TridPage::Unzoom()
00460 {
00461 fGLFrame->fPOV.Undo();
00462 fGLFrame->Update();
00463 }
00464
00465 void TridPage::Rezoom()
00466 {
00467 fGLFrame->fPOV.Redo();
00468 fGLFrame->Update();
00469 }
00470
00471 void TridPage::FullZoom()
00472 {
00473 SetPOV(fFullPOV);
00474 }
00475
00476 void TridPage::AutoZoom()
00477 {
00478 SetPOV(fAutoPOV);
00479 }
00480
00481
00482 void TridPage::SetPOV(TridPOV& pov)
00483 {
00484 fGLFrame->SetPOV(pov);
00485 fGLFrame->Update();
00486 }
00487
00488 double TridPage::PlaceInBox( double boxwidth, double width, int i, int n )
00489 {
00490
00491
00492
00493
00494
00495
00496 double d = (boxwidth - (double)(n)*width)/(double)(n+1);
00497 return d+ (double)(i)*(d+width);
00498 }
00499
00500
00501 void TridPage::ChangeColor()
00502 {
00503 ModifySketches();
00504 fGLFrame->Update();
00505 }
00506
00507 void TridPage::ChangeTrans()
00508 {
00509 ModifySketches();
00510 fGLFrame->Update();
00511 }
00512
00513 void TridPage::ChangePicked()
00514 {
00515 ModifySketches();
00516 fGLFrame->Update();
00517 }
00518
00519 void TridPage::ChangeSelected()
00520 {
00521 ModifySketches();
00522 fGLFrame->Update();
00523 }
00524
00525 void TridPage::ChangeHistograms()
00526 {
00527 }
00528
00529 void TridPage::AnimationRedraw()
00530 {
00531 MSG("TriD",Msg::kDebug) << "TridPage::AnimationRedraw()" << endl;
00532
00533 TridAnimator& ani = fTridControl->GetAnimator();
00534
00535
00536
00537 fGLFrame->SetAnimTime(ani.GetAnimTimeMin(),
00538 ani.GetAnimTimeMax());
00539
00540 if(ani.AnimatingViews()) {
00541 MSG("TriD",Msg::kDebug) << "Rotating from " << fGLFrame->fPOV.GetPhi()
00542 << "to " << fGLFrame->fPOV.GetPhi() + ani.GetViewIncrement()*360.
00543 << endl;
00544 if(fViewMode != kView2D) {
00545 fGLFrame->fPOV.fPhi = (180. + ani.GetFrame()*ani.GetViewIncrement()*360.);
00546 fGLFrame->fPOV.Push();
00547 }
00548 }
00549
00550 if(ani.AnimatingModels()) {
00551 fGLFrame->SetHUDText(Form("Time: %.1f ns to %.1f ns",
00552 1e9*(ani.GetAnimTimeMin()-ani.GetRangeMin()),
00553 1e9*(ani.GetAnimTimeMax()-ani.GetRangeMin())));
00554 }
00555
00556 fGLFrame->Update();
00557
00558 if(ani.Printing()) {
00559 PrintToFile(Form("anim_%s_%04d.png",fWindowName.Data(),ani.GetFrame()),
00560 Form("Time: %.1f ns to %.1f ns",
00561 1e9*(ani.GetAnimTimeMin()-ani.GetRangeMin()),
00562 1e9*(ani.GetAnimTimeMax()-ani.GetRangeMin()))
00563 );
00564 }
00565 }
00566
00567 void TridPage::SaveWindowGeometry(TEnv& env)
00568 {
00569
00570
00571 TString newname(fWindowName);
00572 newname.ReplaceAll(" ","_");
00573
00574
00575
00576 env.SetValue("Trid.DefaultWindows",
00577 Form("%s %s",newname.Data(),env.GetValue("Trid.DefaultWindows",""))
00578 ,kEnvChange);
00579
00580
00581 Int_t x,y;
00582 UInt_t w,h;
00583 if(fGuiBox!=0) {
00584 Window_t wind = (Window_t)(gVirtualX->GetParent(fGuiBox->GetId()));
00585 Window_t root = (Window_t)gClient->GetRoot()->GetId();
00586 Window_t frame = wind;
00587 Window_t parent = wind;
00588 while( (parent != root) && (parent) ) {
00589 frame = parent;
00590 parent = gVirtualX->GetParent(parent);
00591 }
00592 WindowAttributes_t attr;
00593 gVirtualX->GetWindowAttributes(frame,attr);
00594 x = attr.fX;
00595 y = attr.fY;
00596 w = attr.fWidth;
00597 h = attr.fHeight;
00598
00599
00600 env.SetValue(
00601 Form("Trid.WindowGeom.%s",newname.Data()),
00602 Form("%dx%d+%d+%d",w,h,x,y),
00603 kEnvChange);
00604 MSG("TriD",Msg::kDebug)
00605 << "Setting env variable: "
00606 << Form("Trid.WindowGeom.%s",newname.Data())
00607 << "\t=\t"
00608 << Form("%dx%d+%d+%d",w,h,x,y)
00609 << endl;
00610 }
00611 }
00612
00613 void TridPage::RestoreWindowGeometry(TEnv& env)
00614 {
00615 if(fGuiBox!=0) {
00616 Window_t wind = (Window_t)(gVirtualX->GetParent(fGuiBox->GetId()));
00617 Window_t root = (Window_t)gClient->GetRoot()->GetId();
00618 Window_t frame = wind;
00619 Window_t parent = wind;
00620 while( (parent != root) && (parent) ) {
00621 frame = parent;
00622 parent = gVirtualX->GetParent(parent);
00623 }
00624
00625 Int_t x,y;
00626 UInt_t w,h;
00627 WindowAttributes_t attr;
00628 gVirtualX->GetWindowAttributes(frame,attr);
00629 x = attr.fX;
00630 y = attr.fY;
00631 w = attr.fWidth;
00632 h = attr.fHeight;
00633
00634 TString newname(fWindowName);
00635 newname.ReplaceAll(" ","_");
00636 const char* value = env.GetValue(Form("Trid.WindowGeom.%s",newname.Data()),
00637 "");
00638
00639 MSG("TriD",Msg::kDebug) << "Restoring geometry " << Form("Trid.WindowGeom.%s",newname.Data())
00640 << endl;
00641
00642 if(strlen(value)>0) {
00643 sscanf(value,"%ux%u+%d+%d",&w,&h,&x,&y);
00644 MSG("TriD",Msg::kDebug) << "----> Got Value " << value << endl;
00645
00646 gVirtualX->MoveResizeWindow(frame,x,y,w,h);
00647 }
00648 }
00649 }
00650
00651
00652