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