]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/NLTProjectorGL.cxx
First big commit of the mchview program and its accompanying library,
[u/mrichter/AliRoot.git] / EVE / Reve / NLTProjectorGL.cxx
1 // $Header$
2
3 #include "NLTProjectorGL.h"
4 #include <Reve/NLTProjector.h>
5
6 #include <TGLRnrCtx.h>
7 #include <TGLIncludes.h>
8 #include <TGLText.h>
9 #include <TMath.h>
10
11 #include <list>
12
13 using namespace Reve;
14
15 //______________________________________________________________________
16 // NLTProjectorGL
17 //
18
19 ClassImp(NLTProjectorGL)
20
21 NLTProjectorGL::NLTProjectorGL() :
22   TGLObject(),
23
24   fRange(300),
25   fLabelSize(0.02),
26   fLabelOff(0.018),
27   fTMSize(0.02),
28
29   fM(0),
30   fText(0)
31 {
32   fDLCache = kFALSE; // Disable display list.
33   fText = new TGLText();
34   fText->SetGLTextFont(40);
35   fText->SetTextColor(0);
36 }
37
38 NLTProjectorGL::~NLTProjectorGL()
39 {}
40 /**************************************************************************/
41 const char* NLTProjectorGL::GetText(Float_t x) const
42 {
43   using  namespace TMath;
44   // TODO: Form could be replaced with own version of printf
45   if     ( Abs(x) > 1000 )
46   {
47     Float_t v = 10*TMath::Nint(x/10.0f);
48     return Form("%.0f", v);
49   }
50   else if( Abs(x) > 100  )
51   {
52     Float_t v = TMath::Nint(x);
53     return Form("%.0f", v);
54   }
55   else if ( Abs(x) > 10  )
56   {
57     return Form("%.1f", x);
58   }
59   else if ( Abs(x) > 1   )
60   {
61     return Form("%.2f", x);
62   }
63   else
64   {
65     return Form("%.3f", x);
66   }
67 }
68
69 /**************************************************************************/
70 void NLTProjectorGL::SetRange(Float_t pos, Int_t ax) const
71 {
72   using namespace TMath;
73   Float_t limit =  fM->GetProjection()->GetLimit(ax, pos > 0 ? kTRUE: kFALSE);
74   // printf("NLTProjectorGL::SetRange pos %f range %f \n", pos, limit );
75   if ( fM->GetProjection()->GetDistortion() > 0.001 && Abs(pos) > Abs(limit *0.97))
76   {
77     fPos.push_back(limit *0.7);
78     fVals.push_back(fM->GetProjection()->GetValForScreenPos(ax, fPos.back()));
79     // printf("bbox value out of limit:: val %f, pos %f\n", limit, fVals.back());
80   }
81
82   else
83   {
84     fPos.push_back(pos);
85     fVals.push_back(fM->GetProjection()->GetValForScreenPos(ax, fPos.back()));
86   }
87 }
88
89 /**************************************************************************/
90
91 void NLTProjectorGL::DrawTickMarks(Float_t tm) const
92 {
93   glBegin(GL_LINES);
94   for( std::list<Float_t>::iterator pi = fPos.begin(); pi!= fPos.end(); pi++)
95   {
96     glVertex3f(*pi, 0,   0.);
97     glVertex3f(*pi, tm, 0.);
98   }
99   glEnd();
100 }
101
102 /**************************************************************************/
103
104 void NLTProjectorGL::DrawHInfo() const
105 {
106   Float_t tms = fTMSize*fRange;
107   DrawTickMarks(-tms);
108
109   glPushMatrix();
110   glRotatef(-90, 1, 0, 0);
111   glTranslatef(0, 0, -tms -fLabelOff*fRange);
112   const char* txt;
113   Float_t llx, lly, llz, urx, ury, urz;
114   std::list<Float_t>::iterator vi = fVals.begin();
115   for( std::list<Float_t>::iterator pi = fPos.begin(); pi!= fPos.end(); pi++)
116   {
117     txt = GetText(*vi);
118     fText->BBox(txt, llx, lly, llz, urx, ury, urz);
119     fText->PaintGLText(*pi -(urx-llx)*fText->GetTextSize()*0.5, 0, 0, txt);
120     vi++;
121   }
122   glPopMatrix();
123
124   fPos.clear(); fVals.clear();
125 }
126
127 /**************************************************************************/
128 void NLTProjectorGL::DrawVInfo() const
129 {
130   Float_t tms = fTMSize*fRange;
131   glRotatef(90, 0, 0, 1);
132   DrawTickMarks(tms);
133   glRotatef(-90, 0, 0, 1);
134
135   glPushMatrix();
136   glRotatef(-90, 1, 0, 0);
137   glTranslatef(-fLabelOff*fRange -tms, 0, 0);
138   const char* txt;
139   Float_t llx, lly, llz, urx, ury, urz;
140   std::list<Float_t>::iterator vi = fVals.begin();
141   for( std::list<Float_t>::iterator pi = fPos.begin(); pi!= fPos.end(); pi++)
142   {
143     txt= GetText(*vi);
144     fText->BBox(txt, llx, lly, llz, urx, ury, urz);
145     fText->PaintGLText(-(urx-llx)*fText->GetTextSize(), 0, *pi - (ury - lly)*fText->GetTextSize()*0.5, txt);
146     vi++;
147   }
148   glPopMatrix();
149
150   fPos.clear(); fVals.clear();
151 }
152
153 /**************************************************************************/
154 void NLTProjectorGL::SplitInterval(Int_t ax) const
155 {
156   if (fM->GetSplitInfoLevel())
157   {
158     if(fM->GetSplitInfoMode())
159       SplitIntervalByVal(fVals.front(), fVals.back(), ax, 0);
160     else
161       SplitIntervalByPos(fPos.front(), fPos.back(), ax, 0);
162   }
163 }
164
165 /**************************************************************************/
166 void NLTProjectorGL::SplitIntervalByPos(Float_t minp, Float_t maxp, Int_t ax, Int_t level) const
167 {
168   Float_t p = (minp+maxp)*0.5;
169   fPos.push_back(p);
170   Float_t v = fM->GetProjection()->GetValForScreenPos(ax, p);
171   fVals.push_back(v);
172   // printf("level %d position %f value %f\n", level, p,v);
173   level++;
174   if(level<fM->GetSplitInfoLevel())
175   {
176     SplitIntervalByPos(minp, p , ax, level);
177     SplitIntervalByPos(p, maxp, ax, level);
178   }
179 }
180
181 /**************************************************************************/
182 void NLTProjectorGL::SplitIntervalByVal(Float_t minv, Float_t maxv, Int_t ax, Int_t level) const
183 {
184   Float_t v = (minv+maxv)*0.5;
185   fVals.push_back(v);
186   Float_t p = fM->GetProjection()->GetScreenVal(ax, v);
187   fPos.push_back(p);
188   //printf("level %d position %f value %f MINMAX val(%f, %f)\n", level, p,v, minv, maxv);
189   level++;
190   if(level<fM->GetSplitInfoLevel())
191   {
192     SplitIntervalByVal(minv, v , ax, level);
193     SplitIntervalByVal(v, maxv, ax, level);
194   }
195 }
196
197
198 /**************************************************************************/
199 void NLTProjectorGL::DirectDraw(TGLRnrCtx & /*rnrCtx*/) const
200 {
201   // printf("NLTProjectorGL::DirectDraw %d\n.", fM->GetMainColor());
202   GLboolean lightp;
203   glGetBooleanv(GL_LIGHTING, &lightp);
204   if (lightp) glDisable(GL_LIGHTING);
205
206   Float_t* bbox = fM->GetBBox();
207   fRange = bbox[1] - bbox[0];
208   // printf("bbox %f, %f\n", bbox[0], bbox[1]);
209   Vector zeroPos;
210   fM->GetProjection()->ProjectVector(zeroPos);
211   fText->SetTextSize(fLabelSize*fRange);
212   fText->SetTextColor(fM->GetAxisColor());
213
214   { // horizontal
215     glPushMatrix();
216     glTranslatef(0, bbox[2], 0);
217     // left 
218     SetRange(bbox[0], 0);
219     fPos.push_back(zeroPos.x); fVals.push_back(0);
220     SplitInterval(0);
221     DrawHInfo();
222     // right
223     fPos.push_back(zeroPos.x); fVals.push_back(0);
224     SetRange(bbox[1], 0);
225     SplitInterval(0); fVals.pop_front(); fPos.pop_front();
226     DrawHInfo();
227     glPopMatrix();
228   }
229   { // vertical
230     glPushMatrix();
231     glTranslatef(bbox[0], 0, 0);
232     // bottom
233     fPos.push_back(zeroPos.y);fVals.push_back(0);
234     SetRange(bbox[2], 1);
235     SplitInterval(1);
236     DrawVInfo();
237     // top
238     fPos.push_back(zeroPos.y); fVals.push_back(0);
239     SetRange(bbox[3], 1);
240     SplitInterval(1);fPos.pop_front(); fVals.pop_front();
241     DrawVInfo();
242     glPopMatrix();
243   }
244
245   // body
246   glBegin(GL_LINES);
247   glVertex3f(bbox[0], bbox[2], 0.);
248   glVertex3f(bbox[1], bbox[2], 0.);
249   glVertex3f(bbox[0], bbox[2], 0.);
250   glVertex3f(bbox[0], bbox[3], 0.);
251   glEnd();
252
253   Float_t d = 10;
254   if(fM->GetDrawCenter())
255   {
256     Float_t* c = fM->GetProjection()->GetProjectedCenter();
257     glColor3f(1., 0., 0.);
258     glBegin(GL_LINES);
259     glVertex3f(c[0] +d, c[1],    c[2]);     glVertex3f(c[0] - d, c[1]   , c[2]);
260     glVertex3f(c[0] ,   c[1] +d, c[2]);     glVertex3f(c[0]    , c[1] -d, c[2]);
261     glVertex3f(c[0] ,   c[1],    c[2] + d); glVertex3f(c[0]    , c[1]   , c[2] - d);
262     glEnd();
263
264   }
265
266   if(fM->GetDrawOrigin())
267   {
268     Vector zero;
269     fM->GetProjection()->ProjectVector(zero);
270     glColor3f(1., 1., 1.);
271     glBegin(GL_LINES);
272     glVertex3f(zero[0] +d, zero[1],    zero[2]);     glVertex3f(zero[0] - d, zero[1]   , zero[2]);
273     glVertex3f(zero[0] ,   zero[1] +d, zero[2]);     glVertex3f(zero[0]    , zero[1] -d, zero[2]);
274     glVertex3f(zero[0] ,   zero[1],    zero[2] + d); glVertex3f(zero[0]    , zero[1]   , zero[2] - d);
275     glEnd();
276   }
277   if (lightp) glEnable(GL_LIGHTING);
278 }
279
280
281 /**************************************************************************/
282
283 Bool_t NLTProjectorGL::SetModel(TObject* obj, const Option_t* /*opt*/)
284 {
285   if(SetModelCheckClass(obj, NLTProjector::Class())) {
286     fM = dynamic_cast<NLTProjector*>(obj);
287     return kTRUE;
288   }
289   return kFALSE;
290 }
291
292 /**************************************************************************/
293
294 void NLTProjectorGL::SetBBox()
295 {
296   // !! This ok if master sub-classed from TAttBBox
297   SetAxisAlignedBBox(((NLTProjector*)fExternalObj)->AssertBBox());
298 }