Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REveBoxSet.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 "ROOT/REveBoxSet.hxx"
13#include "ROOT/REveShape.hxx"
16
17#include "TRandom.h"
18#include <cassert>
19
20using namespace::ROOT::Experimental;
21
22/** \class REveBoxSet
23\ingroup REve
24Collection of 3D primitives (fixed-size boxes, boxes of different
25sizes, or arbitrary sexto-epipeds, cones). Each primitive can be assigned
26a signal value and a TRef.
27
28A collection of 3D-markers. The way how they are defined depends
29on the fBoxType data-member.
30 - kBT_FreeBox arbitrary box: specify 8*(x,y,z) box corners
31 - kBT_AABox axis-aligned box: specify (x,y,z) and (w, h, d)
32 - kBT_AABoxFixedDim axis-aligned box w/ fixed dimensions: specify (x,y,z)
33 also set fDefWidth, fDefHeight and fDefDepth
34 - kBT_Cone cone defined with position, axis-vector and radius
35 - EllipticCone cone with elliptic base (specify another radius and angle in deg)
36
37Each primitive can be assigned:
38
39 1. Color or signal value. Thresholds and signal-to-color mapping
40 can then be set dynamically via the REveRGBAPalette class.
41 2. External TObject* (stored as TRef).
42
43See also base-class REveDigitSet for more information.
44Tutorial: tutorials/eve/boxset_test.C
45*/
46
47////////////////////////////////////////////////////////////////////////////////
48
49REveBoxSet::REveBoxSet(const char* n, const char* t) :
50 REveDigitSet (n, t),
51
52 fBoxType (kBT_Undef),
53 fDefWidth (1),
54 fDefHeight (1),
55 fDefDepth (1),
56
57 fBoxSkip (0),
58
59 fDrawConeCap (kFALSE)
60{
61 // Constructor.
62
63 // Override from REveDigitSet.
65}
66
67////////////////////////////////////////////////////////////////////////////////
68/// Return size of data-structure describing a box of type bt.
69
71{
72 static const REveException eH("REveBoxSet::SizeofAtom ");
73
74 switch (bt) {
75 case kBT_Undef: return 0;
76 case kBT_FreeBox: return sizeof(BFreeBox_t);
77 case kBT_AABox: return sizeof(BAABox_t);
78 case kBT_AABoxFixedDim: return sizeof(BAABoxFixedDim_t);
79 case kBT_Cone: return sizeof(BCone_t);
80 case kBT_EllipticCone: return sizeof(BEllipticCone_t);
81 case kBT_Hex: return sizeof(BHex_t);
82 default: throw(eH + "unexpected atom type.");
83 }
84 return 0;
85}
86
87////////////////////////////////////////////////////////////////////////////////
88/// Reset the data containers to zero size.
89/// The arguments describe the basic parameters of data storage.
90
91void REveBoxSet::Reset(REveBoxSet::EBoxType_e boxType, Bool_t valIsCol, Int_t chunkSize)
92{
93 fBoxType = boxType;
94 fValueIsColor = valIsCol;
95 fDefaultValue = valIsCol ? 0 : kMinInt;
96 ReleaseIds();
97 fPlex.Reset(SizeofAtom(fBoxType), chunkSize);
98}
99
100////////////////////////////////////////////////////////////////////////////////
101/// Reset the data containers to zero size.
102/// Keep the old data-storage parameters.
103
105{
106 ReleaseIds();
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// Create a new box from a set of 8 vertices.
112/// To be used for box-type kBT_FreeBox.
113
114void REveBoxSet::AddBox(const Float_t* verts)
115{
116 static const REveException eH("REveBoxSet::AddBox ");
117
118 if (fBoxType != kBT_FreeBox)
119 throw(eH + "expect free box-type.");
120
122 memcpy(b->fVertices, verts, sizeof(b->fVertices));
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// Create a new axis-aligned box from at a given position and with
128/// specified dimensions.
129/// To be used for box-type kBT_AABox.
130
132{
133 static const REveException eH("REveBoxSet::AddBox ");
134
135 if (fBoxType != kBT_AABox)
136 throw(eH + "expect axis-aligned box-type.");
137
139 box->fA = a; box->fB = b; box->fC = c;
140 box->fW = w; box->fH = h; box->fD = d;
141}
142
143////////////////////////////////////////////////////////////////////////////////
144/// Create a new axis-aligned box from at a given position.
145/// To be used for box-type kBT_AABoxFixedDim.
146
148{
149 static const REveException eH("REveBoxSet::AddBox ");
150
152 throw(eH + "expect axis-aligned fixed-dimension box-type.");
153
155 box->fA = a; box->fB = b; box->fC = c;
156}
157
158////////////////////////////////////////////////////////////////////////////////
159/// Create a cone with apex at pos, axis dir and radius r.
160/// To be used for box-type kBT_Cone.
161
162void REveBoxSet::AddCone(const REveVector& pos, const REveVector& dir, Float_t r)
163{
164 static const REveException eH("REveBoxSet::AddCone ");
165
166 if (fBoxType != kBT_Cone)
167 throw(eH + "expect cone box-type.");
168
169 BCone_t* cone = (BCone_t*) NewDigit();
170 cone->fPos = pos;
171 cone->fDir = dir;
172 cone->fR = r;
173}
174
175////////////////////////////////////////////////////////////////////////////////
176/// Create a cone with apex at pos, axis dir and radius r.
177/// To be used for box-type kBT_EllipticCone.
178
180 Float_t r, Float_t r2, Float_t angle)
181{
182 static const REveException eH("REveBoxSet::AddEllipticCone ");
183
185 throw(eH + "expect elliptic-cone box-type.");
186
188 cone->fPos = pos;
189 cone->fDir = dir;
190 cone->fR = r;
191 cone->fR2 = r2;
192 cone->fAngle = angle;
193}
194
195////////////////////////////////////////////////////////////////////////////////
196/// Create a hexagonal prism with center of one hexagon at pos, radius of
197/// hexagon vertices r, rotation angle angle (in degrees), and length along z
198/// of depth. To be used for box-type kBT_Hex.
199
200void REveBoxSet::AddHex(const REveVector& pos, Float_t r, Float_t angle, Float_t depth)
201{
202 static const REveException eH("REveBoxSet::AddEllipticCone ");
203
204 if (fBoxType != kBT_Hex)
205 throw(eH + "expect hex box-type.");
206
207 BHex_t* hex = (BHex_t*) NewDigit();
208 hex->fPos = pos;
209 hex->fR = r;
210 hex->fAngle = angle;
211 hex->fDepth = depth;
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Fill bounding-box information of the base-class TAttBBox (virtual method).
216/// If member 'REveFrameBox* fFrame' is set, frame's corners are used as bbox.
217
219{
220 static const REveException eH("REveBoxSet::ComputeBBox ");
221
222 if (fFrame != 0)
223 {
224 BBoxInit();
225 Int_t n = fFrame->GetFrameSize() / 3;
226 Float_t *bbps = fFrame->GetFramePoints();
227 for (int i=0; i<n; ++i, bbps+=3)
228 BBoxCheckPoint(bbps);
229 return;
230 }
231
232 if(fPlex.Size() == 0)
233 {
234 BBoxZero();
235 return;
236 }
237
238 BBoxInit();
239
241 switch (fBoxType)
242 {
243
244 case kBT_FreeBox:
245 {
246 while (bi.next()) {
247 BFreeBox_t& b = * (BFreeBox_t*) bi();
248 for (Int_t i = 0; i < 8; ++i)
249 BBoxCheckPoint(b.fVertices[i]);
250 }
251 break;
252 }
253
254 case kBT_AABox:
255 {
256 while (bi.next()) {
257 BAABox_t& b = * (BAABox_t*) bi();
258 BBoxCheckPoint(b.fA, b.fB, b.fC);
259 BBoxCheckPoint(b.fA + b.fW, b.fB + b.fH , b.fC + b.fD);
260 }
261 break;
262 }
263
265 {
266 while (bi.next()) {
268 BBoxCheckPoint(b.fA, b.fB, b.fC);
269 BBoxCheckPoint(b.fA + fDefWidth, b.fB + fDefHeight , b.fC + fDefDepth);
270 }
271 break;
272 }
273
274 case kBT_Cone:
275 {
276 Float_t mag2=0, mag2Max=0, rMax=0;
277 while (bi.next()) {
278 BCone_t& b = * (BCone_t*) bi();
279 BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
280 mag2 = b.fDir.Mag2();
281 if (mag2>mag2Max) mag2Max=mag2;
282 if (b.fR>rMax) rMax=b.fR;
283 }
284 Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
285 fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
286 fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
287 break;
288 }
289
290 case kBT_EllipticCone:
291 {
292 Float_t mag2=0, mag2Max=0, rMax=0;
293 while (bi.next()) {
294 BEllipticCone_t& b = * (BEllipticCone_t*) bi();
295 BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
296 mag2 = b.fDir.Mag2();
297 if (mag2>mag2Max) mag2Max=mag2;
298 if (b.fR > rMax) rMax = b.fR;
299 if (b.fR2 > rMax) rMax = b.fR2;
300 }
301 Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
302 fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
303 fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
304 break;
305 }
306
307 case kBT_Hex:
308 {
309 while (bi.next()) {
310 BHex_t& h = * (BHex_t*) bi();
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);
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 BBoxCheckPoint(h.fPos.fX - h.fR, h.fPos.fY + h.fR, h.fPos.fZ + h.fDepth);
319 }
320 break;
321 }
322
323 default:
324 {
325 throw(eH + "unsupported box-type.");
326 }
327
328 } // end switch box-type
329}
330
331////////////////////////////////////////////////////////////////////////////////
332/// Fill core part of JSON representation.
333
334Int_t REveBoxSet::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
335{
336 Int_t ret = REveDigitSet::WriteCoreJson(j, rnr_offset);
337 j["boxType"] = int(fBoxType);
338
339 return ret;
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// Crates 3D point array for rendering.
344
346{
347 fRenderData = std::make_unique<REveRenderData>("makeBoxSet", fPlex.Size()*24, 0, fPlex.Size());
348
349 switch (fBoxType)
350 {
352 {
354 while (bi.next())
355 {
357 // vertices
358 for (int c =0; c < 8; c++) {
359 for (int j =0; j < 3; j++)
360 fRenderData->PushV(b.fVertices[c][j]);
361 }
362 }
363 break;
364 }
366 {
368 while (bi.next())
369 {
371 // position
372 fRenderData->PushV(b.fA, b.fB, b.fC);
373 // dimensions
374 fRenderData->PushV(b.fW, b.fH, b.fD);
375 }
376 break;
377 }
378 default:
379 assert(false && "REveBoxSet::BuildRenderData only kBT_FreeBox type supported");
380 }
381
382 //
383 // setup colors
384 //
385 if (fSingleColor == false)
386 {
388 while (bi.next())
389 {
391 if (fValueIsColor)
392 {
393 fRenderData->PushI(int(b.fValue));
394 }
395 else if (fSingleColor == false)
396 {
397 UChar_t c[4] = {0, 0, 0, 0};
398 Bool_t visible = fPalette->ColorFromValue(b.fValue, fDefaultValue, c);
399
400 int value =
401 c[0] +
402 c[1] * 256 +
403 c[2] * 256*256;
404
405 // printf("box val [%d] values (%d, %d, %d) -> int <%d>\n", b.fValue, c[0], c[1], c[2], value);
406
407 // presume transparency 100% when non-visible
408 if (!visible)
409 value += 256*256*256*c[3];
410
411
412 fRenderData->PushI(value);
413 }
414 }
415 }
416
417 if (!fDigitIds.empty())
418 {
419 for (int i = 0; i < fPlex.N(); ++i)
420 {
421 fRenderData->PushI(GetId(i));
422 }
423 }
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Fill the structure with a random set of boxes.
428
430{
431 Reset(kBT_AABox, kTRUE, nboxes);
432 TRandom rnd(0);
433 const Float_t origin = 10, size = 2;
434 Int_t color;
435 for(Int_t i=0; i<nboxes; ++i)
436 {
437 AddBox(origin * rnd.Uniform(-1, 1),
438 origin * rnd.Uniform(-1, 1),
439 origin * rnd.Uniform(-1, 1),
440 size * rnd.Uniform(0.1, 1),
441 size * rnd.Uniform(0.1, 1),
442 size * rnd.Uniform(0.1, 1));
443
444 REveUtil::ColorFromIdx(rnd.Integer(256), (UChar_t*)&color);
445 DigitValue(color);
446 }
447}
ROOT::R::TRInterface & r
Definition Object.C:4
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
const Int_t kMinInt
Definition RtypesCore.h:104
unsigned char UChar_t
Definition RtypesCore.h:38
const Bool_t kFALSE
Definition RtypesCore.h:92
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:91
void AddEllipticCone(const REveVector &pos, const REveVector &dir, Float_t r, Float_t r2, Float_t angle=0)
Create a cone with apex at pos, axis dir and radius r.
void ComputeBBox() override
Fill bounding-box information of the base-class TAttBBox (virtual method).
void AddBox(const Float_t *verts)
Create a new box from a set of 8 vertices.
Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override
Fill core part of JSON representation.
void BuildRenderData() override
Crates 3D point array for rendering.
void Test(Int_t nboxes)
Fill the structure with a random set of boxes.
void AddCone(const REveVector &pos, const REveVector &dir, Float_t r)
Create a cone with apex at pos, axis dir and radius r.
void Reset()
Reset the data containers to zero size.
void AddHex(const REveVector &pos, Float_t r, Float_t angle, Float_t depth)
Create a hexagonal prism with center of one hexagon at pos, radius of hexagon vertices r,...
static Int_t SizeofAtom(EBoxType_e bt)
Return size of data-structure describing a box of type bt.
void Reset(Int_t atom_size, Int_t chunk_size)
Empty the container and reset it with given atom and chunk sizes.
Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override
Fill core part of JSON representation.
DigitBase_t * NewDigit()
Function providing highlight tooltips when always-sec-select is active.
Int_t GetId(Int_t n) const
Set external object reference for digit n.
void ReleaseIds()
Protected method.
void DigitValue(Int_t value)
Set signal value for the last digit added.
std::unique_ptr< REveRenderData > fRenderData
Externally assigned and controlled user data.
REveException Exception-type thrown by Eve classes.
Definition REveTypes.hxx:40
const UChar_t * ColorFromValue(Int_t val) const
static void CheckAndFixBoxOrientationFv(Float_t box[8][3])
Make sure box orientation is consistent with standard arrangement.
static void ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha=kTRUE)
Fill col with RGBA values corresponding to index ci.
Definition REveUtil.cxx:122
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition TAttBBox.h:58
void BBoxZero(Float_t epsilon=0, Float_t x=0, Float_t y=0, Float_t z=0)
Create cube of volume (2*epsilon)^3 at (x,y,z).
Definition TAttBBox.cxx:42
void BBoxInit(Float_t infinity=1e6)
Dynamic Float_t[6] X(min,max), Y(min,max), Z(min,max)
Definition TAttBBox.cxx:29
Float_t * fBBox
Definition TAttBBox.h:20
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition TRandom.cxx:672
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition TRandom.cxx:360
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
const Int_t n
Definition legend1.C:16
Short_t Max(Short_t a, Short_t b)
Definition TMathBase.h:212
Double_t Sqrt(Double_t x)
Definition TMath.h:691