Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TEveBoxSet.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 "TEveBoxSet.h"
13 #include "TEveShape.h"
14 
15 #include "TRandom.h"
16 
17 /** \class TEveBoxSet
18 \ingroup TEve
19 Collection of 3D primitives (fixed-size boxes, boxes of different
20 sizes, or arbitrary sexto-epipeds, cones). Each primitive can be assigned
21 a signal value and a TRef.
22 
23 A collection of 3D-markers. The way how they are defined depends
24 on the fBoxType data-member.
25  - kBT_FreeBox arbitrary box: specify 8*(x,y,z) box corners
26  - kBT_AABox axis-aligned box: specify (x,y,z) and (w, h, d)
27  - kBT_AABoxFixedDim axis-aligned box w/ fixed dimensions: specify (x,y,z)
28  also set fDefWidth, fDefHeight and fDefDepth
29  - kBT_Cone cone defined with position, axis-vector and radius
30  - EllipticCone cone with elliptic base (specify another radius and angle in deg)
31 
32 Each primitive can be assigned:
33 
34  1. Color or signal value. Thresholds and signal-to-color mapping
35  can then be set dynamically via the TEveRGBAPalette class.
36  2. External TObject* (stored as TRef).
37 
38 See also base-class TEveDigitSet for more information.
39 Tutorial: tutorials/eve/boxset_test.C
40 */
41 
42 ClassImp(TEveBoxSet);
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 
46 TEveBoxSet::TEveBoxSet(const char* n, const char* t) :
47  TEveDigitSet (n, t),
48 
49  fBoxType (kBT_Undef),
50  fDefWidth (1),
51  fDefHeight (1),
52  fDefDepth (1),
53 
54  fBoxSkip (0),
55 
56  fDrawConeCap (kFALSE)
57 {
58  // Constructor.
59 
60  // Override from TEveDigitSet.
61  fDisableLighting = kFALSE;
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Return size of data-structure describing a box of type bt.
66 
67 Int_t TEveBoxSet::SizeofAtom(TEveBoxSet::EBoxType_e bt)
68 {
69  static const TEveException eH("TEveBoxSet::SizeofAtom ");
70 
71  switch (bt) {
72  case kBT_Undef: return 0;
73  case kBT_FreeBox: return sizeof(BFreeBox_t);
74  case kBT_AABox: return sizeof(BAABox_t);
75  case kBT_AABoxFixedDim: return sizeof(BAABoxFixedDim_t);
76  case kBT_Cone: return sizeof(BCone_t);
77  case kBT_EllipticCone: return sizeof(BEllipticCone_t);
78  case kBT_Hex: return sizeof(BHex_t);
79  default: throw(eH + "unexpected atom type.");
80  }
81  return 0;
82 }
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 /// Reset the data containers to zero size.
86 /// The arguments describe the basic parameters of data storage.
87 
88 void TEveBoxSet::Reset(TEveBoxSet::EBoxType_e boxType, Bool_t valIsCol, Int_t chunkSize)
89 {
90  fBoxType = boxType;
91  fValueIsColor = valIsCol;
92  fDefaultValue = valIsCol ? 0 : kMinInt;
93  if (fOwnIds)
94  ReleaseIds();
95  fPlex.Reset(SizeofAtom(fBoxType), chunkSize);
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Reset the data containers to zero size.
100 /// Keep the old data-storage parameters.
101 
102 void TEveBoxSet::Reset()
103 {
104  if (fOwnIds)
105  ReleaseIds();
106  fPlex.Reset(SizeofAtom(fBoxType), TMath::Max(fPlex.N(), 64));
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 /// Create a new box from a set of 8 vertices.
111 /// To be used for box-type kBT_FreeBox.
112 
113 void TEveBoxSet::AddBox(const Float_t* verts)
114 {
115  static const TEveException eH("TEveBoxSet::AddBox ");
116 
117  if (fBoxType != kBT_FreeBox)
118  throw(eH + "expect free box-type.");
119 
120  BFreeBox_t* b = (BFreeBox_t*) NewDigit();
121  memcpy(b->fVertices, verts, sizeof(b->fVertices));
122  TEveShape::CheckAndFixBoxOrientationFv(b->fVertices);
123 }
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// Create a new axis-aligned box from at a given position and with
127 /// specified dimensions.
128 /// To be used for box-type kBT_AABox.
129 
130 void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d)
131 {
132  static const TEveException eH("TEveBoxSet::AddBox ");
133 
134  if (fBoxType != kBT_AABox)
135  throw(eH + "expect axis-aligned box-type.");
136 
137  BAABox_t* box = (BAABox_t*) NewDigit();
138  box->fA = a; box->fB = b; box->fC = c;
139  box->fW = w; box->fH = h; box->fD = d;
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Create a new axis-aligned box from at a given position.
144 /// To be used for box-type kBT_AABoxFixedDim.
145 
146 void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c)
147 {
148  static const TEveException eH("TEveBoxSet::AddBox ");
149 
150  if (fBoxType != kBT_AABoxFixedDim)
151  throw(eH + "expect axis-aligned fixed-dimension box-type.");
152 
153  BAABoxFixedDim_t* box = (BAABoxFixedDim_t*) NewDigit();
154  box->fA = a; box->fB = b; box->fC = c;
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Create a cone with apex at pos, axis dir and radius r.
159 /// To be used for box-type kBT_Cone.
160 
161 void TEveBoxSet::AddCone(const TEveVector& pos, const TEveVector& dir, Float_t r)
162 {
163  static const TEveException eH("TEveBoxSet::AddCone ");
164 
165  if (fBoxType != kBT_Cone)
166  throw(eH + "expect cone box-type.");
167 
168  BCone_t* cone = (BCone_t*) NewDigit();
169  cone->fPos = pos;
170  cone->fDir = dir;
171  cone->fR = r;
172 }
173 
174 ////////////////////////////////////////////////////////////////////////////////
175 /// Create a cone with apex at pos, axis dir and radius r.
176 /// To be used for box-type kBT_EllipticCone.
177 
178 void TEveBoxSet::AddEllipticCone(const TEveVector& pos, const TEveVector& dir,
179  Float_t r, Float_t r2, Float_t angle)
180 {
181  static const TEveException eH("TEveBoxSet::AddEllipticCone ");
182 
183  if (fBoxType != kBT_EllipticCone)
184  throw(eH + "expect elliptic-cone box-type.");
185 
186  BEllipticCone_t* cone = (BEllipticCone_t*) NewDigit();
187  cone->fPos = pos;
188  cone->fDir = dir;
189  cone->fR = r;
190  cone->fR2 = r2;
191  cone->fAngle = angle;
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// Create a hexagonal prism with center of one hexagon at pos, radius of
196 /// hexagon vertices r, rotation angle angle (in degrees), and length along z
197 /// of depth. To be used for box-type kBT_Hex.
198 
199 void TEveBoxSet::AddHex(const TEveVector& pos, Float_t r, Float_t angle, Float_t depth)
200 {
201  static const TEveException eH("TEveBoxSet::AddEllipticCone ");
202 
203  if (fBoxType != kBT_Hex)
204  throw(eH + "expect hex box-type.");
205 
206  BHex_t* hex = (BHex_t*) NewDigit();
207  hex->fPos = pos;
208  hex->fR = r;
209  hex->fAngle = angle;
210  hex->fDepth = depth;
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 /// Fill bounding-box information of the base-class TAttBBox (virtual method).
215 /// If member 'TEveFrameBox* fFrame' is set, frame's corners are used as bbox.
216 
217 void TEveBoxSet::ComputeBBox()
218 {
219  static const TEveException eH("TEveBoxSet::ComputeBBox ");
220 
221  if (fFrame != 0)
222  {
223  BBoxInit();
224  Int_t n = fFrame->GetFrameSize() / 3;
225  Float_t *bbps = fFrame->GetFramePoints();
226  for (int i=0; i<n; ++i, bbps+=3)
227  BBoxCheckPoint(bbps);
228  return;
229  }
230 
231  if(fPlex.Size() == 0)
232  {
233  BBoxZero();
234  return;
235  }
236 
237  BBoxInit();
238 
239  TEveChunkManager::iterator bi(fPlex);
240  switch (fBoxType)
241  {
242 
243  case kBT_FreeBox:
244  {
245  while (bi.next()) {
246  BFreeBox_t& b = * (BFreeBox_t*) bi();
247  for (Int_t i = 0; i < 8; ++i)
248  BBoxCheckPoint(b.fVertices[i]);
249  }
250  break;
251  }
252 
253  case kBT_AABox:
254  {
255  while (bi.next()) {
256  BAABox_t& b = * (BAABox_t*) bi();
257  BBoxCheckPoint(b.fA, b.fB, b.fC);
258  BBoxCheckPoint(b.fA + b.fW, b.fB + b.fH , b.fC + b.fD);
259  }
260  break;
261  }
262 
263  case kBT_AABoxFixedDim:
264  {
265  while (bi.next()) {
266  BAABoxFixedDim_t& b = * (BAABoxFixedDim_t*) bi();
267  BBoxCheckPoint(b.fA, b.fB, b.fC);
268  BBoxCheckPoint(b.fA + fDefWidth, b.fB + fDefHeight , b.fC + fDefDepth);
269  }
270  break;
271  }
272 
273  case kBT_Cone:
274  {
275  Float_t mag2=0, mag2Max=0, rMax=0;
276  while (bi.next()) {
277  BCone_t& b = * (BCone_t*) bi();
278  BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
279  mag2 = b.fDir.Mag2();
280  if (mag2>mag2Max) mag2Max=mag2;
281  if (b.fR>rMax) rMax=b.fR;
282  }
283  Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
284  fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
285  fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
286  break;
287  }
288 
289  case kBT_EllipticCone:
290  {
291  Float_t mag2=0, mag2Max=0, rMax=0;
292  while (bi.next()) {
293  BEllipticCone_t& b = * (BEllipticCone_t*) bi();
294  BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
295  mag2 = b.fDir.Mag2();
296  if (mag2>mag2Max) mag2Max=mag2;
297  if (b.fR > rMax) rMax = b.fR;
298  if (b.fR2 > rMax) rMax = b.fR2;
299  }
300  Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
301  fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
302  fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
303  break;
304  }
305 
306  case kBT_Hex:
307  {
308  while (bi.next()) {
309  BHex_t& h = * (BHex_t*) bi();
310  BBoxCheckPoint(h.fPos.fX - h.fR, h.fPos.fY - h.fR, h.fPos.fZ);
311  BBoxCheckPoint(h.fPos.fX + h.fR, h.fPos.fY - h.fR, h.fPos.fZ);
312  BBoxCheckPoint(h.fPos.fX + h.fR, h.fPos.fY + h.fR, h.fPos.fZ);
313  BBoxCheckPoint(h.fPos.fX - h.fR, h.fPos.fY + h.fR, h.fPos.fZ);
314  BBoxCheckPoint(h.fPos.fX - h.fR, h.fPos.fY - h.fR, h.fPos.fZ + h.fDepth);
315  BBoxCheckPoint(h.fPos.fX + h.fR, h.fPos.fY - h.fR, h.fPos.fZ + h.fDepth);
316  BBoxCheckPoint(h.fPos.fX + h.fR, h.fPos.fY + h.fR, h.fPos.fZ + h.fDepth);
317  BBoxCheckPoint(h.fPos.fX - h.fR, h.fPos.fY + h.fR, h.fPos.fZ + h.fDepth);
318  }
319  break;
320  }
321 
322  default:
323  {
324  throw(eH + "unsupported box-type.");
325  }
326 
327  } // end switch box-type
328 }
329 
330 ////////////////////////////////////////////////////////////////////////////////
331 /// Fill the structure with a random set of boxes.
332 
333 void TEveBoxSet::Test(Int_t nboxes)
334 {
335  Reset(kBT_AABox, kTRUE, nboxes);
336  TRandom rnd(0);
337  const Float_t origin = 10, size = 2;
338  Int_t color;
339  for(Int_t i=0; i<nboxes; ++i)
340  {
341  AddBox(origin * rnd.Uniform(-1, 1),
342  origin * rnd.Uniform(-1, 1),
343  origin * rnd.Uniform(-1, 1),
344  size * rnd.Uniform(0.1, 1),
345  size * rnd.Uniform(0.1, 1),
346  size * rnd.Uniform(0.1, 1));
347 
348  TEveUtil::ColorFromIdx(rnd.Integer(256), (UChar_t*)&color);
349  DigitValue(color);
350  }
351 }