]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVE/Reve/QuadSet.cxx
Record changes.
[u/mrichter/AliRoot.git] / EVE / Reve / QuadSet.cxx
CommitLineData
a8b53f69 1// $Header$
2
5a5a1232 3#include "QuadSet.h"
8be1b0cc 4#include "RGBAPalette.h"
5ac9ed05 5#include "RGTopFrame.h"
5a5a1232 6
7#include <TColor.h>
8
9#include <TBuffer3D.h>
10#include <TBuffer3DTypes.h>
11#include <TGeometry.h>
12#include <TVirtualPad.h>
13#include <TVirtualViewer3D.h>
14
15#include <TROOT.h>
16#include <TRandom.h>
17
18
19using namespace Reve;
20
21/**************************************************************************/
22// Quad
23/**************************************************************************/
24ClassImp(Reve::Quad)
25
26void Quad::ColorFromIdx(Color_t ci)
27{
28 TColor* c = gROOT->GetColor(ci);
29 if(c) {
30 UChar_t *x = (UChar_t*) &color;
31 x[0] = (UChar_t)(255*c->GetRed()); x[1] = (UChar_t)(255*c->GetGreen());
32 x[2] = (UChar_t)(255*c->GetBlue()); x[3] = 255;
33 }
34}
35
265ecb21 36Quad::Quad(TRandom& rnd, Float_t origin, Float_t size) : color(0)
5a5a1232 37{
38 ColorFromIdx(Int_t(30*rnd.Rndm()));
39 Float_t x = 2*origin*(rnd.Rndm() - 0.5);
40 Float_t y = 2*origin*(rnd.Rndm() - 0.5);
41 Float_t z = 2*origin*(rnd.Rndm() - 0.5);
42 Float_t* p = vertices;
43 for(int i=0; i<4; ++i) {
44 p[0] = x + 2*size*(rnd.Rndm() - 0.5);
45 p[1] = y + 2*size*(rnd.Rndm() - 0.5);
46 p[2] = z + 2*size*(rnd.Rndm() - 0.5);
47 p += 3;
48 }
49}
50
51/**************************************************************************/
3aa97c5d 52// OldQuadSet
5a5a1232 53/**************************************************************************/
3aa97c5d 54ClassImp(Reve::OldQuadSet)
5a5a1232 55
56
3aa97c5d 57OldQuadSet::OldQuadSet(const Text_t* n, const Text_t* t) :
606c4ed7 58 TNamed(n, t),
265ecb21 59 fQuads(),
606c4ed7 60 fTrans(false)
61{}
5a5a1232 62
3aa97c5d 63void OldQuadSet::Test(Int_t nquads)
5a5a1232 64{
65 TRandom rnd(0);
66 fQuads.resize(nquads);
67 for(Int_t i=0; i<nquads; ++i) {
68 new (&fQuads[i]) Quad(rnd, 10, 2);
69 }
70}
71
3aa97c5d 72void OldQuadSet::Paint(Option_t* )
5a5a1232 73{
74 TBuffer3D buffer(TBuffer3DTypes::kGeneric);
75
76 // Section kCore
77 buffer.fID = this;
78 buffer.fColor = 1;
79 buffer.fTransparency = 0;
80 buffer.fLocalFrame = fTrans;
81 if (fTrans)
82 memcpy(buffer.fLocalMaster, fMatrix, 16*sizeof(Double_t));
83 buffer.SetSectionsValid(TBuffer3D::kCore);
89083271 84
5a5a1232 85 // We fill kCore on first pass and try with viewer
86 Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
87 if (reqSections == TBuffer3D::kNone) {
3aa97c5d 88 // printf("OldQuadSet::Paint viewer was happy with Core buff3d.\n");
5a5a1232 89 return;
90 }
91
92 if (reqSections & TBuffer3D::kRawSizes) {
93 Int_t nbPnts = fQuads.size()*4;
94 Int_t nbSegs = nbPnts;
95 if (!buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, fQuads.size(), fQuads.size()*6)) {
96 return;
97 }
98 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
99 }
100
101 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
102 // Points
103 Int_t pidx = 0;
104 for (std::vector<Quad>::iterator i=fQuads.begin(); i!=fQuads.end(); ++i) {
105 for (Int_t k = 0; k < 12; k++ ){
106 buffer.fPnts[pidx] = (*i).vertices[k];
107 pidx++;
108 }
109 }
110
111 // Segments
112 Int_t sidx = 0;
113 for (Int_t q = 0; q < (Int_t)fQuads.size(); ++q) {
114 for (Int_t s = 0; s < 4; ++s ) {
115 buffer.fSegs[3*sidx ] = 4;
116 buffer.fSegs[3*sidx+1] = sidx;
117 if (s == 3)
118 buffer.fSegs[3*sidx+2] = q*4;
119 else
120 buffer.fSegs[3*sidx+2] = sidx + 1;
121 sidx ++;
122 }
123 }
124
125 // Polygons
126 for (Int_t q = 0; q < (Int_t)fQuads.size(); ++q) {
127 buffer.fPols[6*q] = fQuads[q].color;
128 buffer.fPols[6*q +1] = 4;
c4f03896 129 buffer.fPols[6*q +2] = 4*q + 0;
130 buffer.fPols[6*q +3] = 4*q + 1;
131 buffer.fPols[6*q +4] = 4*q + 2;
132 buffer.fPols[6*q +5] = 4*q + 3;
5a5a1232 133 }
134
135 buffer.SetSectionsValid(TBuffer3D::kRaw);
136 buffer.fColor = 5;
137 }
138
139 gPad->GetViewer3D()->AddObject(buffer);
140}
141
142/**************************************************************************/
143
3aa97c5d 144void OldQuadSet::ComputeBBox()
5a5a1232 145{
146 if(fQuads.empty()) {
606c4ed7 147 BBoxZero();
5a5a1232 148 return;
149 }
606c4ed7 150 BBoxInit();
5a5a1232 151 for(std::vector<Quad>::iterator q=fQuads.begin(); q!=fQuads.end(); ++q) {
152 Float_t* p = q->vertices;
153 for(int i=0; i<4; ++i, p+=3)
606c4ed7 154 BBoxCheckPoint(p);
5a5a1232 155 }
156
157 // printf("%s BBox is x(%f,%f), y(%f,%f), z(%f,%f)\n", GetName(),
606c4ed7 158 // fBBox[0], fBBox[1], fBBox[2], fBBox[3], fBBox[4], fBBox[5]);
5a5a1232 159}
8be1b0cc 160
161/**************************************************************************/
162/**************************************************************************/
163/**************************************************************************/
164/**************************************************************************/
165
166//__________________________________________________________________________
167// QuadSet
168//
169// Supports various internal formats that result in rendering of a
170// set of rectangular objects.
171//
172// Names of internal structures and their variables use fixed
173// assignment to x, z, y coordinates; the render types can override
174// this convention and impose Y as a fixed coordinate.
175// For quad modes the deltas are expected to be positive.
176// For line modes negative deltas are ok.
177
178ClassImp(Reve::QuadSet)
179
180QuadSet::QuadSet(const Text_t* n, const Text_t* t) :
181 RenderElement(),
182 TNamed(n, t),
183
184 fQuadType(QT_Undef),
8be1b0cc 185 fDefaultValue(kMinInt),
bcb20c3e 186 fValueIsColor(kFALSE),
187 fOwnIds (kFALSE),
8be1b0cc 188 fPlex(),
189 fLastQuad(0),
190
191 fDefWidth(1), fDefHeight(1), fDefCoord(0),
192
193 fFrame (0),
3c67f72c 194 fPalette(0),
20358789 195 fRenderMode(RM_Fill),
196 fDisableLigting(kTRUE),
5ac9ed05 197 fEmitSignals(kFALSE),
3c67f72c 198 fHMTrans()
8be1b0cc 199{}
200
201QuadSet::QuadSet(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize,
202 const Text_t* n, const Text_t* t) :
203 RenderElement(),
204 TNamed(n, t),
205
206 fQuadType(quadType),
8be1b0cc 207 fDefaultValue(valIsCol ? 0 : kMinInt),
bcb20c3e 208 fValueIsColor(valIsCol),
209 fOwnIds (kFALSE),
8be1b0cc 210 fPlex(SizeofAtom(quadType), chunkSize),
211 fLastQuad(0),
212
213 fDefWidth(1), fDefHeight(1), fDefCoord(0),
214
215 fFrame (0),
3c67f72c 216 fPalette(0),
20358789 217 fRenderMode(RM_Fill),
218 fDisableLigting(kTRUE),
5ac9ed05 219 fEmitSignals(kFALSE),
3c67f72c 220 fHMTrans()
8be1b0cc 221{}
222
223QuadSet::~QuadSet()
224{
225 SetFrame(0);
226 SetPalette(0);
bcb20c3e 227 if (fOwnIds)
228 ReleaseIds();
229}
230
231void QuadSet::ReleaseIds()
232{
233 VoidCPlex::iterator qi(fPlex);
234 while (qi.next()) {
235 QuadBase& q = * (QuadBase*) qi();
236 if (q.fId.GetObject()) {
237 delete q.fId.GetObject();
238 q.fId = 0;
239 }
240 }
8be1b0cc 241}
242
243/**************************************************************************/
244
245Int_t QuadSet::SizeofAtom(QuadSet::QuadType_e qt)
246{
96c51586 247 static const Exc_t eH("QuadSet::SizeofAtom ");
248
8be1b0cc 249 switch (qt) {
250 case QT_Undef: return 0;
20358789 251 case QT_FreeQuad: return sizeof(QFreeQuad);
252 case QT_RectangleXY: return sizeof(QRect);
253 case QT_RectangleXYFixedDim: return sizeof(QRectFixDim);
254 case QT_RectangleXZFixedY:
255 case QT_RectangleXYFixedZ: return sizeof(QRectFixC);
256 case QT_RectangleXZFixedDimY:
257 case QT_RectangleXYFixedDimZ: return sizeof(QRectFixDimC);
258 case QT_LineXZFixedY:
259 case QT_LineXYFixedZ: return sizeof(QLineFixC);
96c51586 260 case QT_HexagonXY:
261 case QT_HexagonYX: return sizeof(QHex);
262 default: throw(eH + "unexpected atom type.");
8be1b0cc 263 }
264 return 0;
265}
266
267/**************************************************************************/
268
269void QuadSet::Reset(QuadSet::QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize)
270{
271 fQuadType = quadType;
272 fValueIsColor = valIsCol;
273 fDefaultValue = valIsCol ? 0 : kMinInt;
7c30bba9 274 if (fOwnIds)
275 ReleaseIds();
8be1b0cc 276 fPlex.Reset(SizeofAtom(fQuadType), chunkSize);
277}
278
279void QuadSet::RefitPlex()
280{
281 // Instruct underlying memory allocator to regroup itself into a
282 // contiguous memory chunk.
283
284 fPlex.Refit();
285}
286
287/**************************************************************************/
288
289void QuadSet::ScanMinMaxValues(Int_t& min, Int_t& max)
290{
291 if (fValueIsColor || fPlex.Size() == 0) return;
292 min = kMaxInt;
293 max = kMinInt;
294 for (Int_t c=0; c<fPlex.VecSize(); ++c)
295 {
296 Char_t* a = fPlex.Chunk(c);
297 Int_t n = fPlex.NAtoms(c);
298 while (n--)
299 {
300 Int_t v = ((QuadBase*)a)->fValue;
301 if (v < min) min = v;
302 if (v > max) max = v;
303 a += fPlex.S();
304 }
305 }
306 if (min == max)
307 --min;
308}
309
310/**************************************************************************/
311
5ac9ed05 312void QuadSet::SetMainColor(Color_t color)
313{
314 if (fFrame) {
315 fFrame->SetFrameColor(color);
316 fFrame->UpdateBackPtrItems();
317 }
318 gReve->Redraw3D();
319}
320
8be1b0cc 321void QuadSet::SetFrame(FrameBox* b)
322{
323 if (fFrame == b) return;
5ac9ed05 324 if (fFrame) fFrame->DecRefCount(this);
8be1b0cc 325 fFrame = b;
326 if (fFrame) {
5ac9ed05 327 fFrame->IncRefCount(this);
8be1b0cc 328 SetMainColorPtr(fFrame->PtrFrameColor());
329 } else {
330 SetMainColorPtr(0);
331 }
332}
333
334void QuadSet::SetPalette(RGBAPalette* p)
335{
336 if (fPalette == p) return;
337 if (fPalette) fPalette->DecRefCount();
338 fPalette = p;
c4f03896 339 if (fPalette) fPalette->IncRefCount();
8be1b0cc 340}
341
20358789 342RGBAPalette* QuadSet::AssertPalette()
343{
344 if (fPalette == 0) {
345 fPalette = new RGBAPalette;
346 if (!fValueIsColor) {
347 Int_t min, max;
348 ScanMinMaxValues(min, max);
349 fPalette->SetLimits(min, max);
350 fPalette->SetMinMax(min, max);
351 }
352 }
353 return fPalette;
354}
355
8be1b0cc 356/**************************************************************************/
357
358QuadSet::QuadBase* QuadSet::NewQuad()
359{
360 fLastQuad = new (fPlex.NewAtom()) QuadBase(fDefaultValue);
361 return fLastQuad;
362}
363
364void QuadSet::AddQuad(Float_t* verts)
365{
366 static const Exc_t eH("QuadSet::AddQuad ");
20358789 367
8be1b0cc 368 if (fQuadType != QT_FreeQuad)
369 throw(eH + "expect free quad-type.");
370
20358789 371 QFreeQuad* fq = (QFreeQuad*) NewQuad();
8be1b0cc 372 memcpy(fq->fVertices, verts, sizeof(fq->fVertices));
373}
374
375void QuadSet::AddQuad(Float_t x, Float_t y)
376{
377 AddQuad(x, y, fDefCoord, fDefWidth, fDefHeight);
378}
379
380void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z)
381{
382 AddQuad(x, y, z, fDefWidth, fDefHeight);
383}
384
385void QuadSet::AddQuad(Float_t x, Float_t y, Float_t w, Float_t h)
386{
387 AddQuad(x, y, fDefCoord, w, h);
388}
389
390void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z, Float_t w, Float_t h)
391{
392 static const Exc_t eH("QuadSet::AddAAQuad ");
393
20358789 394 QOrigin& fq = * (QOrigin*) NewQuad();
8be1b0cc 395 fq.fX = x; fq.fY = y;
396 switch (fQuadType)
397 {
20358789 398 case QT_RectangleXY: {
399 QRect& q = (QRect&) fq;
8be1b0cc 400 q.fZ = z; q.fW = w; q.fH = h;
401 break;
402 }
20358789 403 case QT_RectangleXYFixedDim: {
404 QRectFixDim& q = (QRectFixDim&) fq;
8be1b0cc 405 q.fZ = z;
406 break;
407 }
20358789 408 case QT_RectangleXZFixedY:
409 case QT_RectangleXYFixedZ: {
410 QRectFixC& q = (QRectFixC&) fq;
8be1b0cc 411 q.fW = w; q.fH = h;
412 break;
413 }
20358789 414 case QT_RectangleXZFixedDimY:
415 case QT_RectangleXYFixedDimZ: {
8be1b0cc 416 break;
417 }
8be1b0cc 418 default:
419 throw(eH + "expect axis-aligned quad-type.");
420 }
421}
422
20358789 423void QuadSet::AddLine(Float_t x, Float_t y, Float_t w, Float_t h)
424{
425 static const Exc_t eH("QuadSet::AddLine ");
426
427 QOrigin& fq = * (QOrigin*) NewQuad();
428 fq.fX = x; fq.fY = y;
429 switch (fQuadType)
430 {
431 case QT_LineXZFixedY:
432 case QT_LineXYFixedZ: {
433 QLineFixC& q = (QLineFixC&) fq;
434 q.fDx = w; q.fDy = h;
435 break;
436 }
437 default:
438 throw(eH + "expect line quad-type.");
439 }
440}
441
96c51586 442void QuadSet::AddHexagon(Float_t x, Float_t y, Float_t z, Float_t r)
443{
444 static const Exc_t eH("QuadSet::AddHexagon ");
445
446 QOrigin& fq = * (QOrigin*) NewQuad();
447 fq.fX = x; fq.fY = y;
448 switch (fQuadType)
449 {
450 case QT_HexagonXY:
451 case QT_HexagonYX: {
452 QHex& q = (QHex&) fq;
453 q.fZ = z; q.fR = r;
454 break;
455 }
456 default:
457 throw(eH + "expect line quad-type.");
458 }
459}
460
8be1b0cc 461/**************************************************************************/
462
463void QuadSet::QuadValue(Int_t value)
464{
465 fLastQuad->fValue = value;
466}
467
468void QuadSet::QuadColor(Color_t ci)
469{
470 ColorFromIdx(ci, (UChar_t*) & fLastQuad->fValue, kTRUE);
471}
472
473void QuadSet::QuadColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
474{
475 UChar_t* x = (UChar_t*) & fLastQuad->fValue;
476 x[0] = r; x[1] = g; x[2] = b; x[3] = a;
477}
478
bcb20c3e 479/**************************************************************************/
480
481void QuadSet::QuadId(TObject* id)
482{
483 fLastQuad->fId = id;
484}
485
486/**************************************************************************/
487
488void QuadSet::QuadSelected(Int_t idx)
489{
5ac9ed05 490 if (fEmitSignals) {
491 CtrlClicked(this, idx);
492 } else {
493 QuadBase* qb = GetQuad(idx);
494 TObject* obj = qb->fId.GetObject();
495 printf("QuadSet::QuadSelected idx=%d, value=%d, obj=0x%lx\n",
496 idx, qb->fValue, (ULong_t)obj);
497 if (obj)
498 obj->Print();
499 }
500}
501
502void QuadSet::CtrlClicked(QuadSet* qs, Int_t idx)
503{
504 Long_t args[2];
505 args[0] = (Long_t) qs;
506 args[1] = (Long_t) idx;
507
508 Emit("CtrlClicked(Reve::Track*, Int_t)", args);
bcb20c3e 509}
510
8be1b0cc 511/**************************************************************************/
512/**************************************************************************/
513
514void QuadSet::ComputeBBox()
515{
f96f6fc7 516 // Fill bounding-box information in base-class TAttBBox (virtual method).
517 // If member 'FrameBox* fFrame' is set, frame's corners are used as bbox.
8be1b0cc 518
f96f6fc7 519 static const Exc_t eH("QuadSet::ComputeBBox ");
8be1b0cc 520
f96f6fc7 521 if (fFrame != 0)
8be1b0cc 522 {
f96f6fc7 523 BBoxInit();
524 Int_t n = fFrame->GetFrameSize() / 3;
525 Float_t *bbps = fFrame->GetFramePoints();
526 for (int i=0; i<n; ++i, bbps+=3)
527 BBoxCheckPoint(bbps);
8be1b0cc 528 }
f96f6fc7 529 else
8be1b0cc 530 {
f96f6fc7 531 if(fPlex.Size() == 0) {
532 BBoxZero();
533 return;
534 }
8be1b0cc 535
f96f6fc7 536 BBoxInit();
537 if (fQuadType == QT_RectangleXYFixedZ ||
538 fQuadType == QT_RectangleXYFixedDimZ)
8be1b0cc 539 {
f96f6fc7 540 fBBox[4] = fDefCoord;
541 fBBox[5] = fDefCoord;
ca462fa9 542 }
f96f6fc7 543 else if (fQuadType == QT_RectangleXZFixedY ||
544 fQuadType == QT_RectangleXZFixedDimY)
ca462fa9 545 {
f96f6fc7 546 fBBox[2] = fDefCoord;
547 fBBox[3] = fDefCoord;
ca462fa9 548 }
8be1b0cc 549
f96f6fc7 550 VoidCPlex::iterator qi(fPlex);
551
552 switch (fQuadType)
ca462fa9 553 {
f96f6fc7 554
555 case QT_FreeQuad:
556 {
557 while (qi.next()) {
558 const Float_t* p = ((QFreeQuad*) qi())->fVertices;
559 BBoxCheckPoint(p); p += 3;
560 BBoxCheckPoint(p); p += 3;
561 BBoxCheckPoint(p); p += 3;
562 BBoxCheckPoint(p);
563 }
564 break;
8be1b0cc 565 }
566
f96f6fc7 567 case QT_RectangleXY:
568 {
569 while (qi.next()) {
570 QRect& q = * (QRect*) qi();
571 if(q.fX < fBBox[0]) fBBox[0] = q.fX;
572 if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
573 if(q.fY < fBBox[2]) fBBox[2] = q.fY;
574 if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
575 if(q.fZ < fBBox[4]) fBBox[4] = q.fZ;
576 if(q.fZ > fBBox[5]) fBBox[5] = q.fZ;
577 }
578 break;
8be1b0cc 579 }
580
f96f6fc7 581 case QT_RectangleXYFixedDim:
582 {
583 const Float_t& w = fDefWidth;
584 const Float_t& h = fDefHeight;
585 while (qi.next()) {
586 QRectFixDim& q = * (QRectFixDim*) qi();
587 if(q.fX < fBBox[0]) fBBox[0] = q.fX;
588 if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
589 if(q.fY < fBBox[2]) fBBox[2] = q.fY;
590 if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
591 if(q.fZ < fBBox[4]) fBBox[4] = q.fZ;
592 if(q.fZ > fBBox[5]) fBBox[5] = q.fZ;
593 }
594 break;
8be1b0cc 595 }
596
f96f6fc7 597 case QT_RectangleXYFixedZ:
598 {
599 while (qi.next()) {
600 QRectFixC& q = * (QRectFixC*) qi();
601 if(q.fX < fBBox[0]) fBBox[0] = q.fX;
602 if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
603 if(q.fY < fBBox[2]) fBBox[2] = q.fY;
604 if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
605 }
606 break;
8be1b0cc 607 }
608
f96f6fc7 609 case QT_RectangleXZFixedY:
610 {
611 while (qi.next()) {
612 QRectFixC& q = * (QRectFixC*) qi();
613 if(q.fX < fBBox[0]) fBBox[0] = q.fX;
614 if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
615 if(q.fY < fBBox[4]) fBBox[4] = q.fY;
616 if(q.fY + q.fH > fBBox[5]) fBBox[5] = q.fY + q.fH;
617 }
618 break;
8be1b0cc 619 }
620
f96f6fc7 621 case QT_RectangleXYFixedDimZ:
622 {
623 const Float_t& w = fDefWidth;
624 const Float_t& h = fDefHeight;
625 while (qi.next()) {
626 QRectFixDimC& q = * (QRectFixDimC*) qi();
627 if(q.fX < fBBox[0]) fBBox[0] = q.fX;
628 if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
629 if(q.fY < fBBox[2]) fBBox[2] = q.fY;
630 if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
631 }
632 break;
8be1b0cc 633 }
634
f96f6fc7 635 case QT_RectangleXZFixedDimY:
636 {
637 const Float_t& w = fDefWidth;
638 const Float_t& h = fDefHeight;
639 while (qi.next()) {
640 QRectFixDimC& q = * (QRectFixDimC*) qi();
641 if(q.fX < fBBox[0]) fBBox[0] = q.fX;
642 if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
643 if(q.fY < fBBox[4]) fBBox[4] = q.fY;
644 if(q.fY + h > fBBox[5]) fBBox[5] = q.fY + h;
645 }
646 break;
8be1b0cc 647 }
648
f96f6fc7 649 case QT_LineXYFixedZ:
650 {
651 while (qi.next()) {
652 QLineFixC& q = * (QLineFixC*) qi();
653 BBoxCheckPoint(q.fX, q.fY, fDefCoord);
654 BBoxCheckPoint(q.fX + q.fDx, q.fY + q.fDy, fDefCoord);
655 }
656 break;
96c51586 657 }
658
f96f6fc7 659 case QT_LineXZFixedY:
660 {
661 while (qi.next()) {
662 QLineFixC& q = * (QLineFixC*) qi();
663 BBoxCheckPoint(q.fX, fDefCoord, q.fY);
664 BBoxCheckPoint(q.fX + q.fDx, fDefCoord, q.fY + q.fDy);
665 }
666 break;
667 }
8be1b0cc 668
f96f6fc7 669 // Ignore 'slight' difference, assume square box for both cases.
670 case QT_HexagonXY:
671 case QT_HexagonYX:
672 {
673 while (qi.next()) {
674 QHex& q = * (QHex*) qi();
675 BBoxCheckPoint(q.fX-q.fR, q.fY-q.fR, q.fZ);
676 BBoxCheckPoint(q.fX+q.fR, q.fY+q.fR, q.fZ);
677 }
678 break;
679 }
680
681 default: {
682 throw(eH + "unsupported quad-type.");
683 }
8be1b0cc 684
f96f6fc7 685 } // end switch quad-type
686 } // end if frame ... else ...
8be1b0cc 687
ca462fa9 688#if ROOT_VERSION_CODE <= ROOT_VERSION(5,14,0)
20358789 689 { // Resize bounding box so that it does not have 0 volume.
690 // This should be done in TAttBBox (via method AssertMinExtents(epsilon)).
691 // Or handled more gracefully in TGLViewer.
692 static const Float_t eps = 1e-3;
693 for (Int_t i=0; i<6; i+=2) {
694 if (fBBox[i+1] - fBBox[i] < eps) {
695 Float_t b = 0.5*(fBBox[i] + fBBox[i+1]);
696 fBBox[i] = b - 0.5*eps;
697 fBBox[i+1] = b + 0.5*eps;
698 }
699 }
700 }
ca462fa9 701#else
702 AssertBBoxExtents(0.001);
703#endif
8be1b0cc 704}
705
706/**************************************************************************/
707
708void QuadSet::Paint(Option_t* /*option*/)
709{
710 static const Exc_t eH("QuadSet::Paint ");
711
712 TBuffer3D buff(TBuffer3DTypes::kGeneric);
713
714 // Section kCore
715 buff.fID = this;
716 buff.fColor = 1;
717 buff.fTransparency = 0;
718 fHMTrans.SetBuffer3D(buff);
719 buff.SetSectionsValid(TBuffer3D::kCore);
720
721 Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
722 if (reqSections != TBuffer3D::kNone)
723 Error(eH, "only direct GL rendering supported.");
724}
725
726/**************************************************************************/