0a7f1ebd8532eded2e6221ffa0ba687d1c4d47ea
[u/mrichter/AliRoot.git] / EVE / Alieve / ITSModuleStepper.cxx
1 // $Header$
2
3 #include "ITSModuleStepper.h"
4 #include "ITSDigitsInfo.h"
5 #include "ITSScaledModule.h"
6
7 #include <TEveManager.h>
8 #include <TEveGedEditor.h>
9 #include <TEveGridStepper.h>
10 #include <TEveGLText.h>
11 #include <TEveTrans.h>
12
13 #include <TObject.h>
14
15 #include <TBuffer3D.h>
16 #include <TBuffer3DTypes.h>
17 #include <TVirtualPad.h>
18 #include <TVirtualViewer3D.h>
19
20 #include <TGLRnrCtx.h>
21 #include <TGLSelectRecord.h>
22 #include <TGLText.h>
23 // #include <FTFont.h>
24 #include <TGLAxis.h>
25 #include <TGLViewer.h>
26 using namespace Alieve;
27
28 //______________________________________________________________________
29 // ITSModuleStepper
30 //
31
32 ClassImp(ITSModuleStepper)
33
34 ITSModuleStepper::ITSModuleStepper(ITSDigitsInfo* di) :
35   TEveElementList("ITS 2DStore", "ITSModuleStepper", kTRUE),
36
37   fPosition(0), 
38     
39   fDigitsInfo(di),
40   fScaleInfo(0),
41
42   fSubDet(-1),
43
44   fStepper(0),
45   fAxis(0),
46   fText(0),
47   fTextSize(0.05),
48   fPagerGap(0.1),
49   fRnrFrame(kFALSE),
50
51   fExpandCell(0.85),
52   fModuleFrameCol(2),
53
54   fPaletteOffset(0.2),
55   fPaletteLength(0.6),
56
57   fWActive(-1),
58   fWWidth(0.025),
59   fWHeight(0.032),
60   fWOff(0.05),
61   fWCol(30),
62   fWActiveCol(45),
63   fFontCol(8)
64 {
65   // override member from base TEveElementList
66   fChildClass = ITSScaledModule::Class();
67
68   SetMainColorPtr(&fWCol);
69
70   fDigitsInfo->IncRefCount();
71
72   fStepper = new TEveGridStepper();
73   fStepper->SetNs(5, 4);
74
75   fScaleInfo = new DigitScaleInfo();
76   fScaleInfo->IncRefCount();
77
78   fAxis = new TGLAxis();
79   fAxis->SetLineColor(4);
80   fAxis->SetTextColor(fFontCol);
81
82   fText = new TGLText();
83   fText->SetTextColor(fFontCol);
84   fText->SetGLTextFont(40);
85   fText->SetGLTextAngles(0, 0, 0);
86   fText->SetTextSize(fTextSize);
87
88   gEve->GetGLViewer()->AddOverlayElement(this);
89 }
90
91 ITSModuleStepper::~ITSModuleStepper()
92 {
93   gEve->GetGLViewer()->RemoveOverlayElement(this);
94
95    fScaleInfo->DecRefCount();
96   fDigitsInfo->DecRefCount();
97
98   delete fStepper;
99
100   delete fAxis;
101   delete fText;
102 }
103
104 /**************************************************************************/
105
106 void ITSModuleStepper::Capacity()
107 {
108   Int_t N = fStepper->GetNx()*fStepper->GetNy();
109   if (N != GetNChildren())
110   {
111     DestroyElements();
112     for (Int_t m=0; m<N; m++) 
113     {
114       AddElement(new ITSScaledModule(m, fDigitsInfo, fScaleInfo));
115     }
116   }
117 }
118
119 /**************************************************************************/
120
121 void ITSModuleStepper::SetFirst(Int_t first)
122 {
123   Int_t lastpage = fIDs.size()/Nxy();
124   if(fIDs.size() % Nxy() ) lastpage++;  
125         
126   Int_t first_lastpage = (lastpage -1)*Nxy();
127   if(first > first_lastpage) first = first_lastpage;
128   if(first < 0) first = 0;
129   fPosition = first;
130   Apply();
131 }
132
133 void ITSModuleStepper::Start()
134 {
135   fPosition = 0;
136   Apply();
137 }
138
139 void ITSModuleStepper::Next()
140 {
141   SetFirst(fPosition + Nxy());
142 }
143
144 void ITSModuleStepper::Previous()
145 {
146   // move to the top left corner first
147   SetFirst(fPosition - Nxy());
148 }
149
150 void ITSModuleStepper::End()
151
152   Int_t lastpage = fIDs.size()/Nxy();
153   if(fIDs.size() % Nxy() ) lastpage++;  
154   fPosition = (lastpage -1)*Nxy();
155
156   fStepper->Reset(); 
157   Apply();
158 }
159
160 /**************************************************************************/
161
162 void ITSModuleStepper::DisplayDet(Int_t det, Int_t layer)
163 {
164   fSubDet = det;
165   fIDs.clear();
166   ITSModuleSelection sel = ITSModuleSelection();
167   sel.fType = det; sel.fLayer=layer;
168   fDigitsInfo->GetModuleIDs(&sel, fIDs);
169   //in reder menu define a space between left and right pager
170   fPagerGap = 1.2*TextLength(Form("%d/%d",GetPages(), GetPages()));
171   Start();
172 }
173
174 /**************************************************************************/
175
176 void ITSModuleStepper::DisplayTheta(Float_t min, Float_t max)
177 {
178   fIDs.clear();
179   ITSModuleSelection sel = ITSModuleSelection();
180   sel.fMaxTheta = max; sel.fMinTheta=min; 
181   fDigitsInfo->GetModuleIDs(&sel, fIDs);
182   Start();
183 }
184
185 /**************************************************************************/
186
187 Int_t ITSModuleStepper::GetCurrentPage()
188 {
189   Int_t idx = fPosition +1; 
190   Int_t n = idx/Nxy();
191   if(idx % Nxy()) n++;
192   return n;
193 }
194
195 /**************************************************************************/
196
197 Int_t ITSModuleStepper::GetPages()
198 {
199   Int_t n = fIDs.size()/Nxy(); 
200   if(fIDs.size() % Nxy()) n++; 
201   return n;
202 }
203   
204 /**************************************************************************/
205
206 void  ITSModuleStepper::Apply()
207 {
208   // printf("ITSModuleStepper::Apply fPosition %d \n", fPosition);
209   gEve->DisableRedraw();
210   Capacity();
211
212   UInt_t idx = fPosition;
213   for(List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
214   {
215     if(idx < fIDs.size()) 
216     {
217       ITSScaledModule* mod = dynamic_cast<ITSScaledModule*>(*childit);
218       mod->SetID(fIDs[idx], kFALSE); 
219       TEveTrans& tr = mod->RefHMTrans();
220       tr.UnitTrans();
221       tr.RotateLF(3,2,TMath::PiOver2());
222       tr.RotateLF(1,3,TMath::PiOver2());   
223
224       // scaling 
225       Float_t mz, mx;
226       Float_t* fp = mod->GetFrame()->GetFramePoints();
227       // switch x,z it will be rotated afterwards
228       mx = -2*fp[0];
229       mz = -2*fp[2];
230
231       // fit width first
232       Double_t sx = fStepper->GetDx();
233       Double_t sy = (mx*fStepper->GetDx())/mz;
234       if(sy > fStepper->GetDy())
235       {
236         //      printf("fit width \n");
237         sy =  fStepper->GetDy();
238         sx =  (mz*fStepper->GetDx())/mx;
239       }
240       Float_t scale = (fExpandCell*sx)/mz;
241       tr.Scale(scale, scale, scale);
242
243       Float_t  p[3];
244       fStepper->GetPosition(p);
245       tr.SetPos(p[0]+0.5*fStepper->GetDx(), p[1]+0.5*fStepper->GetDy(), p[2]+0.5*fStepper->GetDz());
246   
247       if(mod->GetSubDetID() == 2)
248         mod->SetName(Form("SSD %d", idx));
249       else if(mod->GetSubDetID() == 1)
250         mod->SetName(Form("SDD %d", idx));
251       else
252         mod->SetName(Form("SPD %d", idx));
253       mod->SetRnrSelf(kTRUE);
254       mod->UpdateItems();
255
256       fStepper->Step();
257       idx++;
258     }
259     else {
260       (*childit)->SetRnrSelf(kFALSE);
261     }
262   }
263
264   fStepper->Reset();
265   ElementChanged();
266   gEve->EnableRedraw();
267 }
268
269 /**************************************************************************/
270
271 void ITSModuleStepper::Render(TGLRnrCtx& rnrCtx)
272 {
273   // render everyting in relative coordinates
274   glMatrixMode(GL_PROJECTION);
275   glPushMatrix();
276   glLoadIdentity();
277   if (rnrCtx.Selection())
278   {
279     // Should be
280     // glLoadMatrix(rnrCtx.GetCamera()->GetProjMBase());
281     TGLRect rect(*rnrCtx.GetPickRectangle());
282     rnrCtx.GetCamera()->WindowToViewport(rect);
283     gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
284                   (Int_t*) rnrCtx.GetCamera()->RefViewport().CArr());
285   }
286    
287   glMatrixMode(GL_MODELVIEW);
288   glPushMatrix();
289   glLoadIdentity();
290
291   GLboolean lightp;
292   glGetBooleanv(GL_LIGHTING, &lightp);
293   if (lightp) glDisable(GL_LIGHTING);
294
295   glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
296   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
297   glDisable(GL_CULL_FACE);
298   glEnable(GL_BLEND);
299   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
300   RenderMenu();
301   RenderPalette(fPaletteLength, 1.6*fWWidth, fWHeight*0.6);
302   glPopMatrix();
303   glPopAttrib();
304   
305   if (lightp) glEnable(GL_LIGHTING);
306
307   glMatrixMode(GL_PROJECTION);
308   glPopMatrix();
309
310   glMatrixMode(GL_MODELVIEW);
311   RenderCellIDs();
312 }
313
314
315 /**************************************************************************/
316 // Protected sub-renderers
317 /**************************************************************************/
318
319 //______________________________________________________________________
320 Float_t ITSModuleStepper::TextLength(const char* txt)
321 {
322   Float_t llx, lly, llz, urx, ury, urz;
323   fText->BBox(txt, llx, lly, llz, urx, ury, urz);
324   return (urx-llx)*fTextSize;
325 }
326
327 //______________________________________________________________________
328 void ITSModuleStepper::RenderString(TString string, Int_t id)
329 {
330   Float_t txtY = fWHeight*0.5;
331   Float_t txtl = TextLength(string.Data());
332
333   if(id > 0) glLoadName(id);
334   if(id>0 && fWActive == id)
335     fText->SetTextColor(fWActiveCol);
336   else  
337     fText->SetTextColor(fFontCol);
338
339   
340   if(id>0)
341   { 
342     if(fWActive == id) 
343       fText->SetTextColor(fWActiveCol);
344     else
345       fText->SetTextColor(fFontCol);
346
347     glLoadName(id);
348     Float_t ss = fWWidth*0.4;
349     fText->PaintGLText(ss, txtY, -0.8, string.Data());
350     // box
351     Float_t bw =2*ss+txtl;
352     RenderFrame(bw,fWHeight*2,id);
353     glTranslatef( bw, 0, 0);
354   }
355   else 
356   {
357     fText->SetTextColor(fFontCol);
358     fText->PaintGLText(0, txtY, -0.8, string.Data());
359     glTranslatef(txtl, 0, 0);
360   }
361 }
362
363 //______________________________________________________________________
364 void ITSModuleStepper::RenderFrame(Float_t dx, Float_t dy, Int_t id)
365 {
366   if(fRnrFrame == kFALSE)return;
367
368   glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
369   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
370   UChar_t color[4];
371   if (fWActive == id)
372     TEveUtil::ColorFromIdx(fWActiveCol, color);
373   else  
374     TEveUtil:: ColorFromIdx(fWCol, color);
375   glColor4ubv(color);
376
377   glBegin(GL_QUADS);
378   glVertex2f(0, 0);   glVertex2f(dx, 0);
379   glVertex2f(dx, dy); glVertex2f(0, dy);
380   glEnd();
381   glPopAttrib();
382 }
383
384 //______________________________________________________________________
385 void ITSModuleStepper::RenderSymbol(Float_t dx, Float_t dy, Int_t id)
386 {
387   glLoadName(id);
388
389   UChar_t color[4];
390   if (fWActive == id)
391     TEveUtil::ColorFromIdx(fWActiveCol, color);
392   else  
393     TEveUtil::ColorFromIdx(fWCol, color);
394   glColor4ubv(color);
395
396   Float_t xs = dx/4, ys = dy/4;
397   if(id == 0) {
398     glBegin(GL_QUADS);
399     glVertex2f(0,ys); glVertex2f(0, ys*3); 
400     glVertex2f(dx, ys*3); glVertex2f(dx, ys);
401     glEnd();
402     return;
403   }
404
405   glBegin(GL_TRIANGLES);
406   switch (id) {
407     case 1:
408     {
409       // left
410       //      glVertex2f(xs*2.5, ys*3); glVertex2f(xs*1.5, ys*2); glVertex2f(xs*2.5, ys);
411       glVertex2f(xs*3, ys*3); glVertex2f(xs*1, ys*2); glVertex2f(xs*3, ys);
412       break;
413     }
414     case 2:
415     {
416       //double left
417       glVertex2f(xs*2, ys*3); glVertex2f(xs, ys*2);    glVertex2f(xs*2, ys);
418       glVertex2f(xs*3, ys*3); glVertex2f(xs*2, ys*2);  glVertex2f(xs*3, ys);
419       break;
420     }
421     case 3:
422     {
423       // right
424       //glVertex2f(xs*1.5, ys); glVertex2f(xs*2.5, ys*2); glVertex2f(xs*1.5, ys*3);
425       glVertex2f(xs*1, ys); glVertex2f(xs*3, ys*2); glVertex2f(xs*1, ys*3);
426       break;
427     }
428     case 4:
429     {
430       // double right
431       glVertex2f(xs, ys);     glVertex2f(xs*2, ys*2);   glVertex2f(xs, ys*3);
432       glVertex2f(xs*2, ys);   glVertex2f(xs*3, ys*2);   glVertex2f(xs*2, ys*3);
433       break;
434     }
435     case 5:
436     {
437       // up
438       glVertex2f(xs, ys*2.5);  glVertex2f(xs*2, ys*3.5); glVertex2f(xs*3, ys*2.5);
439       break;
440     }
441     case 6:
442     {
443       // down
444       glVertex2f(xs, ys*1.5);  glVertex2f(xs*2, ys*0.5); glVertex2f(xs*3, ys*1.5);
445       break;
446     }
447    
448     default:
449       break;
450   }
451   glEnd();
452   glLoadName(0);
453 }
454
455 //______________________________________________________________________
456 void ITSModuleStepper::RenderPalette(Float_t dx, Float_t x, Float_t y)
457 {
458   glPushMatrix();
459   glLoadIdentity();
460   glTranslatef(1 -x- dx, -1+y*4, 0);
461   ITSModule* qs = dynamic_cast<ITSModule*>(*BeginChildren());
462   TEveRGBAPalette* p = qs->GetPalette();
463   glBegin(GL_QUAD_STRIP);
464   glColor4ubv(p->ColorFromValue(p->GetMinVal()));
465   glVertex2f(0, 0);
466   glVertex2f(0, y);
467   if (p->GetMaxVal() > p->GetMinVal() + 1)
468   {
469     Float_t xs = dx/(p->GetMaxVal() - p->GetMinVal());
470     Float_t x0 = xs;
471     for(Int_t i=p->GetMinVal() + 1; i<p->GetMaxVal(); i++) 
472     {
473       glColor4ubv(p->ColorFromValue(i));
474       glVertex2f(x0, 0);
475       glVertex2f(x0, y);
476       x0+=xs;
477     }
478   }
479   glColor4ubv(p->ColorFromValue(p->GetMaxVal()));
480   glVertex2f(dx, 0);
481   glVertex2f(dx, y);
482   glEnd();
483
484   if (p->GetMaxVal() > p->GetMinVal())
485   {
486     glRotatef(-90,1, 0, 0 );
487     Double_t v1[3] = {0., 0., 0.};
488     Double_t v2[3] = {dx, 0, 0.};
489     fAxis->SetLabelsSize(fTextSize/dx);
490     fAxis->PaintGLAxis(v1, v2, p->GetMinVal(), p->GetMaxVal(), 206);
491   }
492   glPopMatrix();
493 }
494
495 //______________________________________________________________________
496 void ITSModuleStepper::RenderMenu()
497 {
498   Float_t ww = 2*fWWidth;
499   Float_t wh = 2*fWHeight;
500
501   // transparent bar
502   Float_t a=0.3;
503   glColor4f(a, a, a, a);
504   Float_t H = 1.9*wh*(1+ 2*fWOff);
505   if(1) {
506     glBegin(GL_QUADS);
507     glVertex3f(-1, -1,   0.1); glVertex3f(-1, -1+H, 0.1); 
508     glVertex3f(1 , -1+H, 0.1); glVertex3f( 1, -1  , 0.1);
509     glEnd();
510   }
511
512   Float_t y_base = -1 + wh*0.35;
513   glTranslatef(-1, y_base, 0.);
514   glPushName(0);
515   // pager
516   glPushMatrix();
517   glTranslatef(ww, 0, 0.);
518   fText->SetTextSize(fTextSize);
519   Float_t soff = ww*1.3;
520   glTranslatef(0, fWOff*wh, 0);
521   RenderSymbol(ww, wh, 2);
522   RenderFrame(ww,wh,2);
523   glTranslatef(soff, 0, 0);
524   RenderSymbol(ww, wh, 1);
525   RenderFrame(ww,wh,1);
526   glTranslatef(soff, 0, 0);
527   // text info
528   { 
529     const char* txt =  Form("%d/%d ", GetCurrentPage(), GetPages());
530     Float_t dx = (fPagerGap - TextLength(txt))*0.5;
531     fText->SetTextColor(fFontCol);
532     fText->PaintGLText(dx, wh*0.25, -0.8, txt);
533   }
534   glTranslatef(fPagerGap, 0, 0);
535
536   RenderSymbol(ww, wh, 3);
537   RenderFrame(ww,wh,3);
538   glTranslatef(soff, 0, 0);
539   RenderSymbol(ww, wh, 4);
540   RenderFrame(ww,wh,4);
541   glTranslatef(2*ww, 0, 0);
542   glPopMatrix();  
543
544   // scale info
545   glPushMatrix();
546   ITSDigitsInfo* di = fDigitsInfo;
547   Int_t scale = fScaleInfo->GetScale() - 1;
548   ITSScaledModule* sm = dynamic_cast<ITSScaledModule*>(*BeginChildren());
549   Int_t cnx = 0, cnz = 0;
550   switch(sm->GetSubDetID())
551   {
552     case 0: 
553       cnx = di->fSPDScaleX[scale], cnz = di->fSPDScaleZ[scale];
554       break;
555     case 1: 
556       cnx = di->fSDDScaleX[scale], cnz = di->fSDDScaleZ[scale];
557       break;
558     case 2:
559       cnx = di->fSSDScale[scale], cnz = 1;
560       break;
561   }
562   glTranslatef(10*ww,0, 0);
563   RenderString(Form("Zoom: "));
564   glPushMatrix();
565   glTranslatef(0, 0.2*wh, 0);
566   RenderSymbol(ww, wh*0.9, 5);
567   glTranslatef(0, 0.4*wh, 0);
568   RenderFrame(ww, wh*0.5, 5);
569   glPopMatrix();
570   RenderSymbol(ww, wh*0.9, 6);
571   RenderFrame(ww, wh*0.5, 6);
572   glTranslatef(ww, 0, 0);
573   RenderString(Form("%dx%d ", cnx, cnz));
574   glPopMatrix();
575
576   //choose detector
577   glPushMatrix();
578   glTranslatef(18*ww, 0, 0);
579   Float_t bs = ww*0.2;
580   RenderString("SPD", 8);  
581   glTranslatef(bs, 0, 0);
582   RenderString("SDD", 9); 
583   glTranslatef(bs, 0, 0);
584   RenderString("SSD", 10);
585   glPopMatrix();
586
587   glPopName();
588 }
589
590 //______________________________________________________________________
591 void ITSModuleStepper::RenderCellIDs()
592 {
593   fText->SetTextSize(fStepper->GetDy()*0.1);
594   fText->SetTextColor(fFontCol);
595   Double_t x, y, z;
596   Double_t sx, sy, sz;
597   UInt_t idx = fPosition;
598   for (List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
599   {
600     if(idx < fIDs.size()) 
601     { 
602       ITSScaledModule* mod = dynamic_cast<ITSScaledModule*>(*childit);
603       TEveTrans& tr = mod->RefHMTrans();
604       TString name = Form("%d",mod->GetID());
605       tr.GetPos(x,y,z);
606       x += fStepper->GetDx()*0.5;
607       y -= fStepper->GetDy()*0.5;
608       z += 0.4; // !!! MT hack - cross check with overlay rendering.
609       Float_t llx, lly, llz, urx, ury, urz;
610       fText->BBox(name, llx, lly, llz, urx, ury, urz);
611       tr.GetScale(sx, sy, sz);
612       fText->PaintGLText(x-(urx-llx)*sx, y, z, name);
613       idx++;
614     }
615   }
616 }
617
618
619 /**************************************************************************/
620 // Virtual event handlers from TGLOverlayElement
621 /**************************************************************************/
622
623 //______________________________________________________________________
624 Bool_t ITSModuleStepper::Handle(TGLRnrCtx          & /*rnrCtx*/,
625                                 TGLOvlSelectRecord & rec,
626                                 Event_t            * event)
627 {
628   // Handle overlay event.
629   // Return TRUE if event was handled.
630
631   switch (event->fType)
632   { 
633     case kMotionNotify:
634     {
635       Int_t item = rec.GetN() < 2 ? -1 : (Int_t)rec.GetItem(1);
636       if (fWActive != item) {
637         fWActive = item;
638         return kTRUE;
639       } else {
640         return kFALSE;
641       }
642       break;
643     }
644     case kButtonPress:
645     {
646       if (event->fCode != kButton1) {
647         return kFALSE;
648       }
649       switch (rec.GetItem(1))
650       {
651         case 1:
652           Previous();
653           break;
654         case 2:
655           Start();
656           break;
657         case 3:
658           Next();
659           break;
660         case 4:
661           End();
662           break;
663         case 5:
664         {
665           DigitScaleInfo* si = fScaleInfo;
666           if(si->GetScale() < 5) 
667           {
668             si->ScaleChanged(si->GetScale() + 1);       
669             ElementChanged(kTRUE, kTRUE);
670           }
671           break;
672         }
673         case 6:
674         {
675           DigitScaleInfo* si = fScaleInfo;
676           if(si->GetScale() > 1) 
677           {
678             si->ScaleChanged(si->GetScale() - 1);       
679             ElementChanged(kTRUE, kTRUE);
680           }
681           break;
682         }
683         case 7:
684           gEve->GetEditor()->DisplayElement(*BeginChildren());
685           break;
686
687         case 8:
688             DisplayDet(0, -1);
689           break;
690         case 9: 
691             DisplayDet(1, -1);
692           break;
693         case 10: 
694             DisplayDet(2, -1);
695           break;
696         default:
697           break;
698       }
699       return kTRUE;
700       break;
701     }
702     default:
703       break;
704   } // end switch
705   return kFALSE;
706 }
707
708 //______________________________________________________________________
709 Bool_t ITSModuleStepper::MouseEnter(TGLOvlSelectRecord& /*rec*/)
710 {
711   return kTRUE;
712 }
713
714 //______________________________________________________________________
715 void ITSModuleStepper::MouseLeave()
716 {
717   // Mouse has left the element.
718
719   fWActive = -1;
720