Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TEveQuadSet.cxx
Go to the documentation of this file.
1 // @(#)root/eve:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TEveQuadSet.h"
13 
14 #include "TEveManager.h"
15 
16 #include "TColor.h"
17 
18 #include "TBuffer3D.h"
19 #include "TBuffer3DTypes.h"
20 #include "TVirtualPad.h"
21 #include "TVirtualViewer3D.h"
22 
23 #include "TROOT.h"
24 #include "TRandom.h"
25 
26 /** \class TEveQuadSet
27 \ingroup TEve
28 Supports various internal formats that result in rendering of a
29 set of planar (lines, rectangles, hexagons with shared normal) objects.
30 
31 Names of internal structures and their variables use A, B and C as
32 names for coordinate value-holders. Typical assignment is A->X,
33 B->Y, C->Z but each render mode can override this convention and
34 impose y or x as a fixed (third or C) coordinate. Alphabetic order
35 is obeyed in this correspondence.
36 
37 For quad modes the deltas are expected to be positive.
38 For line modes negative deltas are ok.
39 */
40 
41 ClassImp(TEveQuadSet);
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Constructor.
45 
46 TEveQuadSet::TEveQuadSet(const char* n, const char* t) :
47  TEveDigitSet (n, t),
48 
49  fQuadType (kQT_Undef),
50  fDefWidth (1),
51  fDefHeight (1),
52  fDefCoord (0)
53 {
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Constructor.
58 
59 TEveQuadSet::TEveQuadSet(EQuadType_e quadType, Bool_t valIsCol, Int_t chunkSize,
60  const char* n, const char* t) :
61  TEveDigitSet (n, t),
62 
63  fQuadType (kQT_Undef),
64  fDefWidth (1),
65  fDefHeight (1),
66  fDefCoord (0)
67 {
68  Reset(quadType, valIsCol, chunkSize);
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Return size of given atom type.
73 
74 Int_t TEveQuadSet::SizeofAtom(TEveQuadSet::EQuadType_e qt)
75 {
76  static const TEveException eH("TEveQuadSet::SizeofAtom ");
77 
78  switch (qt) {
79  case kQT_Undef: return 0;
80  case kQT_FreeQuad: return sizeof(QFreeQuad_t);
81  case kQT_RectangleXY:
82  case kQT_RectangleXZ:
83  case kQT_RectangleYZ: return sizeof(QRect_t);
84  case kQT_RectangleXYFixedDim: return sizeof(QRectFixDim_t);
85  case kQT_RectangleXYFixedZ:
86  case kQT_RectangleXZFixedY:
87  case kQT_RectangleYZFixedX: return sizeof(QRectFixC_t);
88  case kQT_RectangleXYFixedDimZ:
89  case kQT_RectangleXZFixedDimY:
90  case kQT_RectangleYZFixedDimX: return sizeof(QRectFixDimC_t);
91  case kQT_LineXZFixedY:
92  case kQT_LineXYFixedZ: return sizeof(QLineFixC_t);
93  case kQT_HexagonXY:
94  case kQT_HexagonYX: return sizeof(QHex_t);
95  default: throw(eH + "unexpected atom type.");
96  }
97  return 0;
98 }
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Clear the quad-set and reset the basic parameters.
102 
103 void TEveQuadSet::Reset(TEveQuadSet::EQuadType_e quadType, Bool_t valIsCol,
104  Int_t chunkSize)
105 {
106  fQuadType = quadType;
107  fValueIsColor = valIsCol;
108  fDefaultValue = valIsCol ? 0 : kMinInt;
109  if (fOwnIds)
110  ReleaseIds();
111  fPlex.Reset(SizeofAtom(fQuadType), chunkSize);
112 }
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Add a quad specified with 4 vertices.
116 
117 void TEveQuadSet::AddQuad(Float_t verts[12])
118 {
119  static const TEveException eH("TEveQuadSet::AddQuad ");
120 
121  if (fQuadType != kQT_FreeQuad)
122  throw(eH + "expect free quad-type.");
123 
124  QFreeQuad_t* fq = (QFreeQuad_t*) NewDigit();
125  if (verts != 0)
126  memcpy(fq->fVertices, verts, sizeof(fq->fVertices));
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Add a quad with a and b coordinates. Defaults are applied for
131 /// c coordinate and sizes.
132 
133 void TEveQuadSet::AddQuad(Float_t a, Float_t b)
134 {
135  AddQuad(a, b, fDefCoord, fDefWidth, fDefHeight);
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Add a quad with a, b and c coordinates. Defaults are applied
140 /// for sizes.
141 
142 void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t c)
143 {
144  AddQuad(a, b, c, fDefWidth, fDefHeight);
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 /// Add a quad with a and b coordinates and sizes. Default is applied
149 /// for c coordinate.
150 
151 void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t w, Float_t h)
152 {
153  AddQuad(a, b, fDefCoord, w, h);
154 }
155 
156 ////////////////////////////////////////////////////////////////////////////////
157 /// Add a quad with a, b and c coordinates and sizes.
158 
159 void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h)
160 {
161  static const TEveException eH("TEveQuadSet::AddAAQuad ");
162 
163  QOrigin_t& fq = * (QOrigin_t*) NewDigit();
164  fq.fA = a; fq.fB = b;
165  switch (fQuadType)
166  {
167  case kQT_RectangleXY:
168  case kQT_RectangleXZ:
169  case kQT_RectangleYZ:
170  {
171  QRect_t& q = (QRect_t&) fq;
172  q.fC = c; q.fW = w; q.fH = h;
173  break;
174  }
175 
176  case kQT_RectangleXYFixedDim:
177  {
178  QRectFixDim_t& q = (QRectFixDim_t&) fq;
179  q.fC = c;
180  break;
181  }
182 
183  case kQT_RectangleXYFixedZ:
184  case kQT_RectangleXZFixedY:
185  case kQT_RectangleYZFixedX:
186  {
187  QRectFixC_t& q = (QRectFixC_t&) fq;
188  q.fW = w; q.fH = h;
189  break;
190  }
191 
192  case kQT_RectangleXYFixedDimZ:
193  case kQT_RectangleXZFixedDimY:
194  case kQT_RectangleYZFixedDimX:
195  {
196  break;
197  }
198 
199  default:
200  throw(eH + "expect axis-aligned quad-type.");
201  }
202 }
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// Add a line with starting coordinates and displacements.
206 
207 void TEveQuadSet::AddLine(Float_t a, Float_t b, Float_t w, Float_t h)
208 {
209  static const TEveException eH("TEveQuadSet::AddLine ");
210 
211  QOrigin_t& fq = * (QOrigin_t*) NewDigit();
212  fq.fA = a; fq.fB = b;
213  switch (fQuadType)
214  {
215  case kQT_LineXZFixedY:
216  case kQT_LineXYFixedZ: {
217  QLineFixC_t& q = (QLineFixC_t&) fq;
218  q.fDx = w; q.fDy = h;
219  break;
220  }
221  default:
222  throw(eH + "expect line quad-type.");
223  }
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Add a hexagon with given center (a,b,c) and radius.
228 
229 void TEveQuadSet::AddHexagon(Float_t a, Float_t b, Float_t c, Float_t r)
230 {
231  static const TEveException eH("TEveQuadSet::AddHexagon ");
232 
233  QOrigin_t& fq = * (QOrigin_t*) NewDigit();
234  fq.fA = a; fq.fB = b;
235  switch (fQuadType)
236  {
237  case kQT_HexagonXY:
238  case kQT_HexagonYX: {
239  QHex_t& q = (QHex_t&) fq;
240  q.fC = c; q.fR = r;
241  break;
242  }
243  default:
244  throw eH + "expects hexagon quad-type.";
245  }
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Fill bounding-box information. Virtual from TAttBBox.
250 /// If member 'TEveFrameBox* fFrame' is set, frame's corners are
251 /// used as bbox.
252 
253 void TEveQuadSet::ComputeBBox()
254 {
255  static const TEveException eH("TEveQuadSet::ComputeBBox ");
256 
257  if (fFrame != 0)
258  {
259  BBoxInit();
260  Int_t n = fFrame->GetFrameSize() / 3;
261  Float_t *bbps = fFrame->GetFramePoints();
262  for (int i=0; i<n; ++i, bbps+=3)
263  BBoxCheckPoint(bbps);
264  }
265  else
266  {
267  if(fPlex.Size() == 0) {
268  BBoxZero();
269  return;
270  }
271 
272  BBoxInit();
273  if (fQuadType == kQT_RectangleXYFixedZ ||
274  fQuadType == kQT_RectangleXYFixedDimZ)
275  {
276  fBBox[4] = fDefCoord;
277  fBBox[5] = fDefCoord;
278  }
279  else if (fQuadType == kQT_RectangleXZFixedY ||
280  fQuadType == kQT_RectangleXZFixedDimY)
281  {
282  fBBox[2] = fDefCoord;
283  fBBox[3] = fDefCoord;
284  }
285  else if (fQuadType == kQT_RectangleYZFixedX ||
286  fQuadType == kQT_RectangleYZFixedDimX)
287  {
288  fBBox[0] = fDefCoord;
289  fBBox[1] = fDefCoord;
290  }
291 
292  TEveChunkManager::iterator qi(fPlex);
293 
294  switch (fQuadType)
295  {
296 
297  case kQT_FreeQuad:
298  {
299  while (qi.next()) {
300  const Float_t* p = ((QFreeQuad_t*) qi())->fVertices;
301  BBoxCheckPoint(p); p += 3;
302  BBoxCheckPoint(p); p += 3;
303  BBoxCheckPoint(p); p += 3;
304  BBoxCheckPoint(p);
305  }
306  break;
307  }
308 
309  case kQT_RectangleXY:
310  {
311  while (qi.next()) {
312  QRect_t& q = * (QRect_t*) qi();
313  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
314  if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
315  if(q.fB < fBBox[2]) fBBox[2] = q.fB;
316  if(q.fB + q.fH > fBBox[3]) fBBox[3] = q.fB + q.fH;
317  if(q.fC < fBBox[4]) fBBox[4] = q.fC;
318  if(q.fC > fBBox[5]) fBBox[5] = q.fC;
319  }
320  break;
321  }
322 
323  case kQT_RectangleXZ:
324  {
325  while (qi.next()) {
326  QRect_t& q = * (QRect_t*) qi();
327  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
328  if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
329  if(q.fB < fBBox[4]) fBBox[4] = q.fB;
330  if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
331  if(q.fC < fBBox[2]) fBBox[2] = q.fC;
332  if(q.fC > fBBox[3]) fBBox[3] = q.fC;
333  }
334  break;
335  }
336 
337  case kQT_RectangleYZ:
338  {
339  while (qi.next()) {
340  QRect_t& q = * (QRect_t*) qi();
341  if(q.fA < fBBox[2]) fBBox[2] = q.fA;
342  if(q.fA + q.fW > fBBox[3]) fBBox[3] = q.fA + q.fW;
343  if(q.fB < fBBox[4]) fBBox[4] = q.fB;
344  if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
345  if(q.fC < fBBox[0]) fBBox[0] = q.fC;
346  if(q.fC > fBBox[1]) fBBox[1] = q.fC;
347  }
348  break;
349  }
350 
351  case kQT_RectangleXYFixedDim:
352  {
353  const Float_t& w = fDefWidth;
354  const Float_t& h = fDefHeight;
355  while (qi.next()) {
356  QRectFixDim_t& q = * (QRectFixDim_t*) qi();
357  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
358  if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w;
359  if(q.fB < fBBox[2]) fBBox[2] = q.fB;
360  if(q.fB + h > fBBox[3]) fBBox[3] = q.fB + h;
361  if(q.fC < fBBox[4]) fBBox[4] = q.fC;
362  if(q.fC > fBBox[5]) fBBox[5] = q.fC;
363  }
364  break;
365  }
366 
367  case kQT_RectangleXYFixedZ:
368  {
369  while (qi.next()) {
370  QRectFixC_t& q = * (QRectFixC_t*) qi();
371  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
372  if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
373  if(q.fB < fBBox[2]) fBBox[2] = q.fB;
374  if(q.fB + q.fH > fBBox[3]) fBBox[3] = q.fB + q.fH;
375  }
376  break;
377  }
378 
379  case kQT_RectangleXZFixedY:
380  {
381  while (qi.next()) {
382  QRectFixC_t& q = * (QRectFixC_t*) qi();
383  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
384  if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
385  if(q.fB < fBBox[4]) fBBox[4] = q.fB;
386  if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
387  }
388  break;
389  }
390 
391  case kQT_RectangleYZFixedX:
392  {
393  while (qi.next()) {
394  QRectFixC_t& q = * (QRectFixC_t*) qi();
395  if(q.fA < fBBox[2]) fBBox[2] = q.fA;
396  if(q.fA + q.fW > fBBox[3]) fBBox[3] = q.fA + q.fW;
397  if(q.fB < fBBox[4]) fBBox[4] = q.fB;
398  if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
399  }
400  break;
401  }
402 
403  case kQT_RectangleXYFixedDimZ:
404  {
405  const Float_t& w = fDefWidth;
406  const Float_t& h = fDefHeight;
407  while (qi.next()) {
408  QRectFixDimC_t& q = * (QRectFixDimC_t*) qi();
409  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
410  if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w;
411  if(q.fB < fBBox[2]) fBBox[2] = q.fB;
412  if(q.fB + h > fBBox[3]) fBBox[3] = q.fB + h;
413  }
414  break;
415  }
416 
417  case kQT_RectangleXZFixedDimY:
418  {
419  const Float_t& w = fDefWidth;
420  const Float_t& h = fDefHeight;
421  while (qi.next()) {
422  QRectFixDimC_t& q = * (QRectFixDimC_t*) qi();
423  if(q.fA < fBBox[0]) fBBox[0] = q.fA;
424  if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w;
425  if(q.fB < fBBox[4]) fBBox[4] = q.fB;
426  if(q.fB + h > fBBox[5]) fBBox[5] = q.fB + h;
427  }
428  break;
429  }
430 
431  case kQT_RectangleYZFixedDimX:
432  {
433  const Float_t& w = fDefWidth;
434  const Float_t& h = fDefHeight;
435  while (qi.next()) {
436  QRectFixDimC_t& q = * (QRectFixDimC_t*) qi();
437  if(q.fA < fBBox[2]) fBBox[2] = q.fA;
438  if(q.fA + w > fBBox[3]) fBBox[3] = q.fA + w;
439  if(q.fB < fBBox[4]) fBBox[4] = q.fB;
440  if(q.fB + h > fBBox[5]) fBBox[5] = q.fB + h;
441  }
442  break;
443  }
444 
445  // TEveLine modes
446 
447  case kQT_LineXYFixedZ:
448  {
449  while (qi.next()) {
450  QLineFixC_t& q = * (QLineFixC_t*) qi();
451  BBoxCheckPoint(q.fA, q.fB, fDefCoord);
452  BBoxCheckPoint(q.fA + q.fDx, q.fB + q.fDy, fDefCoord);
453  }
454  break;
455  }
456 
457  case kQT_LineXZFixedY:
458  {
459  while (qi.next()) {
460  QLineFixC_t& q = * (QLineFixC_t*) qi();
461  BBoxCheckPoint(q.fA, fDefCoord, q.fB);
462  BBoxCheckPoint(q.fA + q.fDx, fDefCoord, q.fB + q.fDy);
463  }
464  break;
465  }
466 
467  // Hexagon modes
468 
469  // Ignore 'slight' difference, assume square box for both cases.
470  case kQT_HexagonXY:
471  case kQT_HexagonYX:
472  {
473  while (qi.next()) {
474  QHex_t& q = * (QHex_t*) qi();
475  BBoxCheckPoint(q.fA-q.fR, q.fB-q.fR, q.fC);
476  BBoxCheckPoint(q.fA+q.fR, q.fB+q.fR, q.fC);
477  }
478  break;
479  }
480 
481  default:
482  {
483  throw(eH + "unsupported quad-type.");
484  }
485 
486  } // end switch quad-type
487  } // end if frame ... else ...
488 }