]>
Commit | Line | Data |
---|---|---|
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 | ||
19 | using namespace Reve; | |
20 | ||
21 | /**************************************************************************/ | |
22 | // Quad | |
23 | /**************************************************************************/ | |
24 | ClassImp(Reve::Quad) | |
25 | ||
26 | void 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 | 36 | Quad::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 | 54 | ClassImp(Reve::OldQuadSet) |
5a5a1232 | 55 | |
56 | ||
3aa97c5d | 57 | OldQuadSet::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 | 63 | void 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 | 72 | void 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 | 144 | void 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 | ||
178 | ClassImp(Reve::QuadSet) | |
179 | ||
180 | QuadSet::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 | ||
201 | QuadSet::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 | ||
223 | QuadSet::~QuadSet() | |
224 | { | |
225 | SetFrame(0); | |
226 | SetPalette(0); | |
bcb20c3e | 227 | if (fOwnIds) |
228 | ReleaseIds(); | |
229 | } | |
230 | ||
231 | void 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 | ||
245 | Int_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 | ||
269 | void 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 | ||
279 | void 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 | ||
289 | void 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 | 312 | void QuadSet::SetMainColor(Color_t color) |
313 | { | |
314 | if (fFrame) { | |
315 | fFrame->SetFrameColor(color); | |
316 | fFrame->UpdateBackPtrItems(); | |
317 | } | |
318 | gReve->Redraw3D(); | |
319 | } | |
320 | ||
8be1b0cc | 321 | void 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 | ||
334 | void 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 | 342 | RGBAPalette* 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 | ||
358 | QuadSet::QuadBase* QuadSet::NewQuad() | |
359 | { | |
360 | fLastQuad = new (fPlex.NewAtom()) QuadBase(fDefaultValue); | |
361 | return fLastQuad; | |
362 | } | |
363 | ||
364 | void 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 | ||
375 | void QuadSet::AddQuad(Float_t x, Float_t y) | |
376 | { | |
377 | AddQuad(x, y, fDefCoord, fDefWidth, fDefHeight); | |
378 | } | |
379 | ||
380 | void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z) | |
381 | { | |
382 | AddQuad(x, y, z, fDefWidth, fDefHeight); | |
383 | } | |
384 | ||
385 | void QuadSet::AddQuad(Float_t x, Float_t y, Float_t w, Float_t h) | |
386 | { | |
387 | AddQuad(x, y, fDefCoord, w, h); | |
388 | } | |
389 | ||
390 | void 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 | 423 | void 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 | 442 | void 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 | ||
463 | void QuadSet::QuadValue(Int_t value) | |
464 | { | |
465 | fLastQuad->fValue = value; | |
466 | } | |
467 | ||
468 | void QuadSet::QuadColor(Color_t ci) | |
469 | { | |
470 | ColorFromIdx(ci, (UChar_t*) & fLastQuad->fValue, kTRUE); | |
471 | } | |
472 | ||
473 | void 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 | ||
481 | void QuadSet::QuadId(TObject* id) | |
482 | { | |
483 | fLastQuad->fId = id; | |
484 | } | |
485 | ||
486 | /**************************************************************************/ | |
487 | ||
488 | void 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 | ||
502 | void 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 | ||
514 | void 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 | ||
708 | void 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 | /**************************************************************************/ |