29 ClassImp(TEveProjectionAxesGL);
34 TEveProjectionAxesGL::TEveProjectionAxesGL() :
46 Bool_t TEveProjectionAxesGL::SetModel(TObject* obj,
const Option_t* )
48 fM = SetModelDynCast<TEveProjectionAxes>(obj);
49 fAxisPainter.SetAttAxis(fM);
50 return fM->GetManager() ? kTRUE : kFALSE;
57 void TEveProjectionAxesGL::SetBBox()
59 SetAxisAlignedBBox(((TEveProjectionAxes*)fExternalObj)->AssertBBox());
65 void TEveProjectionAxesGL::FilterOverlappingLabels(Int_t idx, Float_t ref)
const
67 TGLAxisPainter::LabVec_t &orig = fAxisPainter.RefLabVec();
68 if (orig.size() == 0)
return;
70 Float_t center = fM->GetManager()->GetProjection()->GetProjectedCenter()[idx];
77 Float_t minD = TMath::Abs(orig[0].first -center);
78 for (TGLAxisPainter::LabVec_t::iterator it = orig.begin(); it != orig.end(); ++it)
80 currD = TMath::Abs((*it).first - center);
90 TGLAxisPainter::LabVec_t filtered;
91 filtered.push_back(orig[minIdx]);
92 Int_t size = orig.size();
93 Float_t minDist = 4*fM->GetLabelSize()*ref;
99 pos = orig[minIdx].first;
100 for (Int_t i=minIdx-1; i>=0; --i)
102 if (TMath::Abs(pos - orig[i].first) > minDist)
104 filtered.push_back(orig[i]);
111 if (minIdx < (size -1))
113 pos = orig[minIdx].first;
114 for (Int_t i=minIdx+1; i<size; ++i)
116 if (TMath::Abs(orig[i].first - pos) > minDist)
118 filtered.push_back(orig[i]);
125 if (filtered.size() >= 2)
128 fAxisPainter.SetTextFormat(orig.front().second, orig.back().second, orig[minIdx].second - orig[minIdx-1].second);
130 fAxisPainter.SetTextFormat(orig.front().second, orig.back().second, orig[minIdx+1].second - orig[minIdx].second);
132 fAxisPainter.RefLabVec().swap(filtered);
136 fAxisPainter.SetTextFormat(orig.front().second, orig.back().second, orig.back().second - orig.front().second);
143 void TEveProjectionAxesGL::SplitInterval(Float_t p1, Float_t p2, Int_t ax)
const
145 fAxisPainter.RefLabVec().clear();
146 fAxisPainter.RefTMVec().clear();
152 fAxisPainter.RefTMVec().push_back(TGLAxisPainter::TM_t(p1, -1));
154 if (fM->GetLabMode() == TEveProjectionAxes::kValue)
156 SplitIntervalByVal(p1, p2, ax);
158 else if (fM->GetLabMode() == TEveProjectionAxes::kPosition)
160 SplitIntervalByPos(p1, p2, ax);
167 void TEveProjectionAxesGL::SplitIntervalByPos(Float_t p1, Float_t p2, Int_t ax)
const
170 Int_t n1a = TMath::FloorNint(fM->GetNdivisions() / 100);
171 Int_t n2a = fM->GetNdivisions() - n1a * 100;
174 Double_t bl1=0, bh1=0, bl2=0, bh2=0;
175 THLimitsFinder::Optimize(p1, p2, n1a, bl1, bh1, bn1, bw1);
176 THLimitsFinder::Optimize(bl1, bl1+bw1, n2a, bl2, bh2, bn2, bw2);
178 Int_t n1=TMath::CeilNint(p1/bw1);
179 Int_t n2=TMath::FloorNint(p2/bw1);
181 TGLAxisPainter::LabVec_t &labVec = fAxisPainter.RefLabVec();
182 TGLAxisPainter::TMVec_t &tmVec = fAxisPainter.RefTMVec();
186 for (Int_t l=n1; l<=n2; l++)
189 labVec.push_back( TGLAxisPainter::Lab_t(p , fProjection->GetValForScreenPos(ax, p)));
192 tmVec.push_back(TGLAxisPainter::TM_t(p, 0));
194 for (Int_t i=1; i<bn2; i++)
196 if (pMinor > p2)
break;
197 tmVec.push_back( TGLAxisPainter::TM_t(pMinor, 1));
204 pMinor = n1*bw1 -bw2;
207 tmVec.push_back(TGLAxisPainter::TM_t(pMinor, 1));
215 void TEveProjectionAxesGL::SplitIntervalByVal(Float_t p1, Float_t p2, Int_t ax)
const
218 TGLAxisPainter::LabVec_t &labVec = fAxisPainter.RefLabVec();
219 TGLAxisPainter::TMVec_t &tmVec = fAxisPainter.RefTMVec();
222 Int_t n1a = TMath::FloorNint(fM->GetNdivisions() / 100);
223 Int_t n2a = fM->GetNdivisions() - n1a * 100;
226 Double_t bl1=0, bh1=0, bl2=0, bh2=0;
227 Float_t v1 = fProjection->GetValForScreenPos(ax, p1);
228 Float_t v2 = fProjection->GetValForScreenPos(ax, p2);
229 THLimitsFinder::Optimize(v1, v2, n1a, bl1, bh1, bn1, bw1);
230 THLimitsFinder::Optimize(bl1, bl1+bw1, n2a, bl2, bh2, bn2, bw2);
232 Float_t pFirst, pSecond;
237 fProjection->SetDirectionalVector(ax, dirVec);
239 fProjection->GetOrthogonalCenter(ax, oCenter);
242 for (Int_t l=0; l<=bn1; l++)
245 pFirst = fProjection->GetScreenVal(ax, v);
246 labVec.push_back(TGLAxisPainter::Lab_t(pFirst , v));
247 tmVec.push_back(TGLAxisPainter::TM_t(pFirst, 0));
250 for (Int_t k=1; k<bn2; k++)
252 pSecond = fProjection->GetScreenVal(ax, v+k*bw2, dirVec, oCenter);
253 if (pSecond > p2)
break;
254 tmVec.push_back(TGLAxisPainter::TM_t(pSecond, 1));
263 pSecond = fProjection->GetScreenVal(ax, v, dirVec, oCenter);
264 if (pSecond < p1)
break;
265 tmVec.push_back(TGLAxisPainter::TM_t(pSecond, 1));
273 void TEveProjectionAxesGL::GetRange(Int_t ax, Float_t frustMin, Float_t frustMax, Float_t& min, Float_t& max)
const
275 Float_t* bb = fM->fManager->GetBBox();
277 Float_t bbMin = bb[ax*2];
278 Float_t bbMax = bb[ax*2 + 1];
279 Float_t off = ( bb[ax*2 + 1] - bb[ax*2]) * 0.5;
285 if (frustMin > bbMin) {
287 min += (frustMax - frustMin) * 0.1;
294 if (frustMax < bbMax) {
296 max -= (frustMax - frustMin) * 0.1;
306 void TEveProjectionAxesGL::Draw(TGLRnrCtx& rnrCtx)
const
308 if (rnrCtx.IsDrawPassOutlineLine())
311 TGLObject::Draw(rnrCtx);
318 void TEveProjectionAxesGL::DirectDraw(TGLRnrCtx& rnrCtx)
const
320 if (rnrCtx.Selection() || rnrCtx.Highlight() || fM->fManager->GetBBox() == 0)
return;
322 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
324 glDisable(GL_LIGHTING);
325 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
326 glEnable(GL_COLOR_MATERIAL);
327 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
328 glDisable(GL_CULL_FACE);
331 Float_t old_depth_range[2];
332 glGetFloatv(GL_DEPTH_RANGE, old_depth_range);
333 glDepthRange(0, 0.001);
336 TGLCamera &camera = rnrCtx.RefCamera();
337 Float_t l = -camera.FrustumPlane(TGLCamera::kLeft).D();
338 Float_t r = camera.FrustumPlane(TGLCamera::kRight).D();
339 Float_t t = camera.FrustumPlane(TGLCamera::kTop).D();
340 Float_t b = -camera.FrustumPlane(TGLCamera::kBottom).D();
342 if (fM->fUseColorSet)
344 TGLUtil::Color(rnrCtx.ColorSet().Markup());
345 fAxisPainter.SetUseAxisColors(kFALSE);
348 fProjection = fM->GetManager()->GetProjection();
349 glDisable(GL_LIGHTING);
352 Float_t d = ((r-l) > (b-t)) ? (b-t) : (r-l);
354 if (fM->GetDrawCenter())
356 Float_t* c = fProjection->GetProjectedCenter();
357 TGLUtil::LineWidth(1);
359 glVertex3f(c[0] + d, c[1], c[2]); glVertex3f(c[0] - d, c[1], c[2]);
360 glVertex3f(c[0], c[1] + d, c[2]); glVertex3f(c[0], c[1] - d, c[2]);
361 glVertex3f(c[0], c[1], c[2] + d); glVertex3f(c[0], c[1], c[2] - d);
364 if (fM->GetDrawOrigin())
367 fProjection->ProjectVector(zero, 0);
368 TGLUtil::LineWidth(1);
370 glVertex3f(zero[0] + d, zero[1], zero[2]); glVertex3f(zero[0] - d, zero[1], zero[2]);
371 glVertex3f(zero[0], zero[1] + d, zero[2]); glVertex3f(zero[0], zero[1] - d, zero[2]);
372 glVertex3f(zero[0], zero[1], zero[2] + d); glVertex3f(zero[0], zero[1], zero[2] - d);
380 using namespace TMath;
382 glGetIntegerv(GL_VIEWPORT, vp);
383 Float_t refLength = TMath::Sqrt((TMath::Power(vp[2]-vp[0], 2) + TMath::Power(vp[3]-vp[1], 2)));
384 Float_t tickLength = TMath::Sqrt((TMath::Power(r-l, 2) + TMath::Power(t-b, 2)));
385 fAxisPainter.SetFontMode(TGLFont::kPixmap);
386 fAxisPainter.SetLabelFont(rnrCtx, TGLFontManager::GetFontNameFromId(fM->GetLabelFont()), TMath::CeilNint(refLength*fM->GetLabelSize()), tickLength*fM->GetLabelSize());
390 if (fM->fAxesMode == TEveProjectionAxes::kAll ||
391 fM->fAxesMode == TEveProjectionAxes::kHorizontal)
393 GetRange(0, l, r, min, max);
394 SplitInterval(min, max, 0);
396 FilterOverlappingLabels(0, r-l);
397 fAxisPainter.RefTMVec().push_back(TGLAxisPainter::TM_t(max, -1));
399 fAxisPainter.RefDir().Set(1, 0, 0);
400 fAxisPainter.RefTMOff(0).Set(0, tickLength, 0);
404 glTranslatef( 0, b, 0);
405 fAxisPainter.SetLabelAlign(TGLFont::kCenterH, TGLFont::kTop);
406 fAxisPainter.RnrLabels();
407 fAxisPainter.RnrLines();
412 glTranslatef( 0, t, 0);
413 fAxisPainter.SetLabelAlign(TGLFont::kCenterH, TGLFont::kBottom);
414 fAxisPainter.RefTMOff(0).Negate();
415 fAxisPainter.RnrLabels();
416 fAxisPainter.RnrLines();
421 if (fM->fAxesMode == TEveProjectionAxes::kAll ||
422 fM->fAxesMode == TEveProjectionAxes::kVertical)
424 GetRange(1, b, t, min, max);
425 SplitInterval(min, max, 1);
427 FilterOverlappingLabels(1, t-b);
428 fAxisPainter.RefTMVec().push_back(TGLAxisPainter::TM_t(max, -1));
430 fAxisPainter.RefDir().Set(0, 1, 0);
431 fAxisPainter.RefTMOff(0).Set(tickLength, 0 , 0);
435 glTranslatef(l, 0, 0);
436 fAxisPainter.SetLabelAlign(TGLFont::kLeft, TGLFont::kCenterV);
437 fAxisPainter.RnrLabels();
438 fAxisPainter.RnrLines();
443 glTranslatef(r, 0, 0);
444 fAxisPainter.SetLabelAlign(TGLFont::kRight, TGLFont::kCenterV);
445 fAxisPainter.RefTMOff(0).Negate();
446 fAxisPainter.RnrLabels();
447 fAxisPainter.RnrLines();
451 catch (TEveException& exc)
453 Warning(
"TEveProjectionAxesGL::DirectDraw",
"caught exception: '%s'.", exc.Data());
456 glDepthRange(old_depth_range[0], old_depth_range[1]);