]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/QuadSet.cxx
8cd1e98b5a75befa1a2eaf31d06e7775aa9f5060
[u/mrichter/AliRoot.git] / EVE / Reve / QuadSet.cxx
1 // $Header$
2
3 #include "QuadSet.h"
4 #include "RGBAPalette.h"
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
18 using namespace Reve;
19
20 /**************************************************************************/
21 // Quad
22 /**************************************************************************/
23 ClassImp(Reve::Quad)
24
25 void 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
35 Quad::Quad(TRandom& rnd, Float_t origin, Float_t size) : color(0)
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 /**************************************************************************/
51 // OldQuadSet
52 /**************************************************************************/
53 ClassImp(Reve::OldQuadSet)
54
55
56 OldQuadSet::OldQuadSet(const Text_t* n, const Text_t* t) :
57   TNamed(n, t),
58   fQuads(),
59   fTrans(false)
60 {}
61
62 void OldQuadSet::Test(Int_t nquads)
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
71 void OldQuadSet::Paint(Option_t* )
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) {
87     // printf("OldQuadSet::Paint viewer was happy with Core buff3d.\n");
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;
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;
132     }
133
134     buffer.SetSectionsValid(TBuffer3D::kRaw);
135     buffer.fColor = 5;
136   }
137    
138   gPad->GetViewer3D()->AddObject(buffer);
139 }
140
141 /**************************************************************************/
142
143 void OldQuadSet::ComputeBBox()
144 {
145   if(fQuads.empty()) {
146     BBoxZero();
147     return;
148   }
149   BBoxInit();
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)
153       BBoxCheckPoint(p);
154   }
155
156   // printf("%s BBox is x(%f,%f), y(%f,%f), z(%f,%f)\n", GetName(),
157   //        fBBox[0], fBBox[1], fBBox[2], fBBox[3], fBBox[4], fBBox[5]);
158 }
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
177 ClassImp(Reve::QuadSet)
178
179 QuadSet::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),
192   fPalette(0),
193   fRenderMode(RM_AsIs),
194   fHMTrans()
195 {}
196
197 QuadSet::QuadSet(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize,
198                  const Text_t* n, const Text_t* t) :
199   RenderElement(),
200   TNamed(n, t),
201
202   fQuadType(quadType),
203   fValueIsColor(valIsCol),
204   fDefaultValue(valIsCol ? 0 : kMinInt),
205   fPlex(SizeofAtom(quadType), chunkSize),
206   fLastQuad(0),
207
208   fDefWidth(1), fDefHeight(1), fDefCoord(0),
209
210   fFrame  (0),
211   fPalette(0),
212   fRenderMode(RM_AsIs),
213   fHMTrans()
214 {}
215
216 QuadSet::~QuadSet()
217 {
218   SetFrame(0);
219   SetPalette(0);
220 }
221
222 /**************************************************************************/
223
224 Int_t QuadSet::SizeofAtom(QuadSet::QuadType_e qt)
225 {
226   switch (qt) {
227     case QT_Undef:                return 0;
228     case QT_FreeQuad:             return sizeof(FreeQuad);
229     case QT_AxisAligned:          return sizeof(AAQuad);
230     case QT_AxisAlignedFixedDim:  return sizeof(AAFixDimQuad);
231     case QT_AxisAlignedFixedY:
232     case QT_AxisAlignedFixedZ:    return sizeof(AAFixZQuad);
233     case QT_AxisAlignedFixedDimY:
234     case QT_AxisAlignedFixedDimZ: return sizeof(AAFixDimZQuad);
235     case QT_LineFixedY:
236     case QT_LineFixedZ:           return sizeof(LineFixedZ);
237   }
238   return 0;
239 }
240
241 /**************************************************************************/
242
243 void QuadSet::Reset(QuadSet::QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize)
244 {
245   fQuadType     = quadType;
246   fValueIsColor = valIsCol;
247   fDefaultValue = valIsCol ? 0 : kMinInt;
248   fPlex.Reset(SizeofAtom(fQuadType), chunkSize);
249 }
250
251 void QuadSet::RefitPlex()
252 {
253   // Instruct underlying memory allocator to regroup itself into a
254   // contiguous memory chunk.
255
256   fPlex.Refit();
257 }
258
259 /**************************************************************************/
260
261 void QuadSet::ScanMinMaxValues(Int_t& min, Int_t& max)
262 {
263   if (fValueIsColor || fPlex.Size() == 0) return;
264   min = kMaxInt;
265   max = kMinInt;
266   for (Int_t c=0; c<fPlex.VecSize(); ++c)
267   {
268     Char_t* a = fPlex.Chunk(c);
269     Int_t   n = fPlex.NAtoms(c);
270     while (n--)
271     {
272       Int_t v = ((QuadBase*)a)->fValue;
273       if (v < min) min = v;
274       if (v > max) max = v;
275       a += fPlex.S();
276     }
277   }
278   if (min == max)
279     --min;
280 }
281
282 /**************************************************************************/
283
284 void QuadSet::SetFrame(FrameBox* b)
285 {
286   if (fFrame == b) return;
287   if (fFrame) fFrame->DecRefCount();
288   fFrame = b;
289   if (fFrame) {
290     fFrame->IncRefCount();
291     SetMainColorPtr(fFrame->PtrFrameColor());
292   } else {
293     SetMainColorPtr(0);
294   }
295 }
296
297 void QuadSet::SetPalette(RGBAPalette* p)
298 {
299   if (fPalette == p) return;
300   if (fPalette) fPalette->DecRefCount();
301   fPalette = p;
302   if (fPalette) {
303     fPalette->IncRefCount();
304     SetMainColorPtr(fPalette->PtrDefaultColor());
305   } else {
306     SetMainColorPtr(0);
307   }
308 }
309
310 /**************************************************************************/
311
312 QuadSet::QuadBase* QuadSet::NewQuad()
313 {
314   fLastQuad = new (fPlex.NewAtom()) QuadBase(fDefaultValue);
315   return fLastQuad;
316 }
317
318 void QuadSet::AddQuad(Float_t* verts)
319 {
320   static const Exc_t eH("QuadSet::AddQuad ");
321   if (fQuadType != QT_FreeQuad)
322     throw(eH + "expect free quad-type.");
323
324   FreeQuad* fq = (FreeQuad*) NewQuad();
325   memcpy(fq->fVertices, verts, sizeof(fq->fVertices));
326 }
327
328 void QuadSet::AddQuad(Float_t x, Float_t y)
329 {
330   AddQuad(x, y, fDefCoord, fDefWidth, fDefHeight);
331 }
332
333 void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z)
334 {
335   AddQuad(x, y, z, fDefWidth, fDefHeight);
336 }
337
338 void QuadSet::AddQuad(Float_t x, Float_t y, Float_t w, Float_t h)
339 {
340   AddQuad(x, y, fDefCoord, w, h);
341 }
342
343 void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z, Float_t w, Float_t h)
344 {
345   static const Exc_t eH("QuadSet::AddAAQuad ");
346
347   AAFixDimZQuad& fq = * (AAFixDimZQuad*) NewQuad();
348   fq.fX = x; fq.fY = y;
349   switch (fQuadType)
350   {
351     case QT_AxisAligned: {
352       AAQuad& q = (AAQuad&) fq;
353       q.fZ = z; q.fW = w; q.fH = h;
354       break;
355     }
356     case QT_AxisAlignedFixedDim: {
357       AAFixDimQuad& q =  (AAFixDimQuad&) fq;
358       q.fZ = z;
359       break;
360     }
361     case QT_AxisAlignedFixedY:
362     case QT_AxisAlignedFixedZ: {
363       AAFixZQuad& q = (AAFixZQuad&) fq;
364       q.fW = w; q.fH = h;
365       break;
366     }
367     case QT_AxisAlignedFixedDimY:
368     case QT_AxisAlignedFixedDimZ: {
369       break;
370     }
371     case QT_LineFixedY:
372     case QT_LineFixedZ: {
373       LineFixedZ& q = (LineFixedZ&) fq;
374       q.fDx = w; q.fDy = h;
375       break;
376     }
377     default:
378       throw(eH + "expect axis-aligned quad-type.");
379   }
380 }
381
382 /**************************************************************************/
383
384 void QuadSet::QuadValue(Int_t value)
385 {
386   fLastQuad->fValue = value;
387 }
388
389 void QuadSet::QuadColor(Color_t ci)
390 {
391   ColorFromIdx(ci, (UChar_t*) & fLastQuad->fValue, kTRUE);
392 }
393
394 void QuadSet::QuadColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
395 {
396   UChar_t* x = (UChar_t*) & fLastQuad->fValue;
397   x[0] = r; x[1] = g; x[2] = b; x[3] = a;
398 }
399
400 /**************************************************************************/
401 /**************************************************************************/
402
403 void QuadSet::ComputeBBox()
404 {
405   static const Exc_t eH("QuadSet::ComputeBBox ");
406
407   // !!!! Missing handling of FrameBox !!!!
408   // It shoud even simpify things ...
409
410   if(fPlex.Size() == 0) {
411     BBoxZero();
412     return;
413   }
414
415   BBoxInit();
416   if (fQuadType == QT_AxisAlignedFixedZ    ||
417       fQuadType == QT_AxisAlignedFixedDimZ)
418   {
419     fBBox[4] = fDefCoord;
420     fBBox[5] = fDefCoord;
421   }
422   else if (fQuadType == QT_AxisAlignedFixedY    ||
423            fQuadType == QT_AxisAlignedFixedDimY)
424   {
425     fBBox[2] = fDefCoord;
426     fBBox[3] = fDefCoord;
427   }
428
429   for (Int_t c=0; c<fPlex.VecSize(); ++c)
430   {
431     QuadBase* qbp = (QuadBase*) fPlex.Chunk(c);
432     Int_t       n = fPlex.NAtoms(c);
433
434     switch (fQuadType)
435     {
436
437       case QT_FreeQuad:
438       {
439         FreeQuad* qp = (FreeQuad*) qbp;
440         while (n--) {
441           Float_t* p = qp->fVertices;
442           BBoxCheckPoint(p); p += 3;
443           BBoxCheckPoint(p); p += 3;
444           BBoxCheckPoint(p); p += 3;
445           BBoxCheckPoint(p);
446           ++qp;
447         }
448         break;
449       }
450
451       case QT_AxisAligned:
452       {
453         AAQuad* qp = (AAQuad*) qbp;
454         while (n--) {
455           AAQuad& q = * qp;
456           if(q.fX        < fBBox[0]) fBBox[0] = q.fX;
457           if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
458           if(q.fY        < fBBox[2]) fBBox[2] = q.fY;
459           if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
460           if(q.fZ        < fBBox[4]) fBBox[4] = q.fZ;
461           if(q.fZ        > fBBox[5]) fBBox[5] = q.fZ;
462           ++qp;
463         }
464         break;
465       }
466
467       case QT_AxisAlignedFixedDim:
468       {
469         AAFixDimQuad* qp =  (AAFixDimQuad*) qbp;
470         const Float_t& w = fDefWidth;
471         const Float_t& h = fDefHeight;
472         while (n--) {
473           AAFixDimQuad& q = * qp;
474           if(q.fX     < fBBox[0]) fBBox[0] = q.fX;
475           if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
476           if(q.fY     < fBBox[2]) fBBox[2] = q.fY;
477           if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
478           if(q.fZ     < fBBox[4]) fBBox[4] = q.fZ;
479           if(q.fZ     > fBBox[5]) fBBox[5] = q.fZ;
480           ++qp;
481         }
482         break;
483       }
484
485       case QT_AxisAlignedFixedZ:
486       {
487         AAFixZQuad* qp = (AAFixZQuad*) qbp;
488         while (n--) {
489           AAFixZQuad& q = * qp;
490           if(q.fX        < fBBox[0]) fBBox[0] = q.fX;
491           if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
492           if(q.fY        < fBBox[2]) fBBox[2] = q.fY;
493           if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
494           ++qp;
495         }
496         break;
497       }
498
499       case QT_AxisAlignedFixedY:
500       {
501         AAFixZQuad* qp = (AAFixZQuad*) qbp;
502         while (n--) {
503           AAFixZQuad& q = * qp;
504           if(q.fX        < fBBox[0]) fBBox[0] = q.fX;
505           if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
506           if(q.fY        < fBBox[4]) fBBox[4] = q.fY;
507           if(q.fY + q.fH > fBBox[5]) fBBox[5] = q.fY + q.fH;
508           ++qp;
509         }
510         break;
511       }
512
513       case QT_AxisAlignedFixedDimZ:
514       {
515         AAFixDimZQuad* qp =  (AAFixDimZQuad*) qbp;
516         const Float_t& w = fDefWidth;
517         const Float_t& h = fDefHeight;
518         while (n--) {
519           AAFixDimZQuad& q = * qp;
520           if(q.fX     < fBBox[0]) fBBox[0] = q.fX;
521           if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
522           if(q.fY     < fBBox[2]) fBBox[2] = q.fY;
523           if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
524           ++qp;
525         }
526         break;
527       }
528
529       case QT_AxisAlignedFixedDimY:
530       {
531         AAFixDimZQuad* qp =  (AAFixDimZQuad*) qbp;
532         const Float_t& w = fDefWidth;
533         const Float_t& h = fDefHeight;
534         while (n--) {
535           AAFixDimZQuad& q = * qp;
536           if(q.fX     < fBBox[0]) fBBox[0] = q.fX;
537           if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
538           if(q.fY     < fBBox[4]) fBBox[4] = q.fY;
539           if(q.fY + h > fBBox[5]) fBBox[5] = q.fY + h;
540           ++qp;
541         }
542         break;
543       }
544
545       case QT_LineFixedZ:
546       {
547         LineFixedZ* qp =  (LineFixedZ*) qbp;
548         while (n--) {
549           LineFixedZ& q = * qp;
550           BBoxCheckPoint(q.fX,         q.fY,         fDefCoord);
551           BBoxCheckPoint(q.fX + q.fDx, q.fY + q.fDy, fDefCoord);
552           ++qp;
553         }
554         break;
555       }
556
557       case QT_LineFixedY:
558       {
559         LineFixedZ* qp =  (LineFixedZ*) qbp;
560         while (n--) {
561           LineFixedZ& q = * qp;
562           BBoxCheckPoint(q.fX,         fDefCoord, q.fY);
563           BBoxCheckPoint(q.fX + q.fDx, fDefCoord, q.fY + q.fDy);
564           ++qp;
565         }
566         break;
567       }
568
569       default: {
570         throw(eH + "unsupported quad-type.");
571       }
572
573     } // end switch quad-type
574
575   } // end for chunk
576
577 }
578
579 /**************************************************************************/
580
581 void QuadSet::Paint(Option_t* /*option*/)
582 {
583   static const Exc_t eH("QuadSet::Paint ");
584
585   TBuffer3D buff(TBuffer3DTypes::kGeneric);
586
587   // Section kCore
588   buff.fID           = this;
589   buff.fColor        = 1;
590   buff.fTransparency = 0;
591   fHMTrans.SetBuffer3D(buff);
592   buff.SetSectionsValid(TBuffer3D::kCore);
593
594   Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
595   if (reqSections != TBuffer3D::kNone)
596     Error(eH, "only direct GL rendering supported.");
597 }
598
599 /**************************************************************************/