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#include "ROOT/REveManager.hxx"
17#include "ROOT/REveTrans.hxx"
18
19#include "TRandom.h"
20#include <cassert>
21
22#include <nlohmann/json.hpp>
23
24using namespace::ROOT::Experimental;
25
26/** \class REveBoxSet
27\ingroup REve
28Collection of 3D primitives (fixed-size boxes, boxes of different
29sizes, or arbitrary sexto-epipeds, cones). Each primitive can be assigned
30a signal value and a TRef.
31
32A collection of 3D-markers. The way how they are defined depends
33on the fBoxType data-member.
34 - kBT_FreeBox arbitrary box: specify 8*(x,y,z) box corners
35 - kBT_AABox axis-aligned box: specify (x,y,z) and (w, h, d)
36 - kBT_AABoxFixedDim axis-aligned box w/ fixed dimensions: specify (x,y,z)
37 also set fDefWidth, fDefHeight and fDefDepth
38 - kBT_Cone cone defined with position, axis-vector and radius
39 - EllipticCone cone with elliptic base (specify another radius and angle in deg)
40
41Each primitive can be assigned:
42
43 1. Color or signal value. Thresholds and signal-to-color mapping
44 can then be set dynamically via the REveRGBAPalette class.
45 2. External TObject* (stored as TRef).
46
47See also base-class REveDigitSet for more information.
48Tutorial: tutorials/eve/boxset_test.C
49*/
50
51////////////////////////////////////////////////////////////////////////////////
52
53REveBoxSet::REveBoxSet(const char* n, const char* t) :
54 REveDigitSet (n, t),
55
56 fBoxType (kBT_Undef),
57
58 fBoxSkip (0),
59
60 fDrawConeCap (kFALSE)
61{
62 // Constructor.
63
64 // Override from REveDigitSet.
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Return size of data-structure describing a box of type bt.
70
72{
73 static const REveException eH("REveBoxSet::SizeofAtom ");
74
75 switch (bt) {
76 case kBT_Undef: return 0;
77 case kBT_FreeBox: return sizeof(BFreeBox_t);
78 case kBT_Instanced: return sizeof(Instanced_t);
79 case kBT_InstancedScaled: return sizeof(InstancedScaled_t);
81 default: throw(eH + "unexpected atom type.");
82 }
83 return 0;
84}
85
86////////////////////////////////////////////////////////////////////////////////
87/// Reset the data containers to zero size.
88/// The arguments describe the basic parameters of data storage.
89
90void REveBoxSet::Reset(REveBoxSet::EBoxType_e boxType, Bool_t valIsCol, Int_t chunkSize)
91{
92 fBoxType = boxType;
93 fValueIsColor = valIsCol;
94 fDefaultValue = valIsCol ? 0 : kMinInt;
95 ReleaseIds();
96 fPlex.Reset(SizeofAtom(fBoxType), chunkSize);
97}
98
99////////////////////////////////////////////////////////////////////////////////
100/// Reset the data containers to zero size.
101/// Keep the old data-storage parameters.
102
104{
105 ReleaseIds();
107}
108
109////////////////////////////////////////////////////////////////////////////////
110/// Create a new box from a set of 8 vertices.
111/// To be used for box-type kBT_FreeBox.
112
114{
115 static const REveException eH("REveBoxSet::AddBox ");
116
117 if (fBoxType != kBT_FreeBox)
118 throw(eH + "expect free box-type.");
119
121 memcpy(b->fVertices, verts, sizeof(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
131{
132 static const REveException eH("REveBoxSet::AddBox ");
133
135 throw(eH + "expect axis-aligned box-type.");
136
138 box->fX = a; box->fY = b; box->fZ = 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
147{
148 static const REveException eH("REveBoxSet::AddBox ");
149
150 if (fBoxType != kBT_Instanced)
151 throw(eH + "expect axis-aligned fixed-dimension box-type.");
152
154 box->fX = a; box->fY = b; box->fZ = c;
155}
156
157////////////////////////////////////////////////////////////////////////////////
158/// Create shape with arbitrary transformtaion
159///
161{
162 static const REveException eH("REveBoxSet::AddMat4Box ");
164 throw(eH + "expect Mat4 box-type.");
165
167 memcpy(b->fMat, arr, sizeof(b->fMat));
168}
169
170////////////////////////////////////////////////////////////////////////////////
171/// Create a cone with apex at pos, axis dir and radius r.
172/// To be used for box-type kBT_Cone.
173
174void REveBoxSet::AddCone(const REveVector& pos, const REveVector& dir, Float_t r)
175{
176 static const REveException eH("REveBoxSet::AddCone ");
177 using namespace TMath;
179
180 REveTrans t;
181 float h = dir.Mag();
182 float phi = ATan2(dir.fY, dir.fX);
183 float theta = ATan (dir.fZ / Sqrt(dir.fX*dir.fX + dir.fY*dir.fY));
184
185 theta = Pi()/2 -theta;
186 t.RotateLF(1, 2, phi);
187 t.RotateLF(3, 1, theta);
188 t.SetScale(r, r, h);
189 t.SetPos(pos.fX, pos.fY, pos.fZ);
190
192 for(Int_t i=0; i<16; ++i)
193 cone->fMat[i] = t[i];
194}
195
196////////////////////////////////////////////////////////////////////////////////
197/// Create a cone with apex at pos, axis dir and radius r.
198/// To be used for box-type kBT_EllipticCone.
199
202{
203 static const REveException eH("REveBoxSet::AddEllipticCone ");
204 using namespace TMath;
206 REveTrans t;
207 float h = dir.Mag();
208 float phi = ATan2(dir.fY, dir.fX);
209 float theta = ATan (dir.fZ / Sqrt(dir.fX*dir.fX + dir.fY*dir.fY));
210
211 theta = Pi()/2 -theta;
212 t.RotateLF(1, 2, phi);
213 t.RotateLF(3, 1, theta);
214 t.RotateLF(1, 2, angle * TMath::DegToRad());
215 t.SetScale(r, r2, h);
216 t.SetPos(pos.fX, pos.fY, pos.fZ);
217
219 for(Int_t i=0; i<16; ++i)
220 cone->fMat[i] = t[i];
221}
222
223////////////////////////////////////////////////////////////////////////////////
224/// Create a hexagonal prism with center of one hexagon at pos, radius of
225/// hexagon vertices r, rotation angle angle (in degrees), and length along z
226/// of depth. To be used for box-type kBT_Hex.
227
229{
230 static const REveException eH("REveBoxSet::AddHex ");
231
233 throw(eH + "expect hex box-type.");
234
235 fShapeType = kHex;
236
238 REveTrans t; // AMT do we need to reuse ???
239 t.SetPos(pos.fX, pos.fY, pos.fZ);
240 t.SetScale(r,r,depth);
241 t.RotatePF(1, 2, angle);
242 for(Int_t i=0; i<16; ++i)
243 hex->fMat[i] = t[i];
244}
245////////////////////////////////////////////////////////////////////////////////
246/// Fill bounding-box information of the base-class TAttBBox (virtual method).
247/// If member 'REveFrameBox* fFrame' is set, frame's corners are used as bbox.
248
250{
251 static const REveException eH("REveBoxSet::ComputeBBox ");
252
253 if (fFrame != nullptr)
254 {
255 BBoxInit();
256 Int_t n = fFrame->GetFrameSize() / 3;
257 Float_t *bbps = fFrame->GetFramePoints();
258 for (int i=0; i<n; ++i, bbps+=3)
259 BBoxCheckPoint(bbps);
260 return;
261 }
262
263 if(fPlex.Size() == 0)
264 {
265 BBoxZero();
266 return;
267 }
268
269 BBoxInit();
270
272 switch (fBoxType)
273 {
274
275 case kBT_FreeBox:
276 {
277 while (bi.next()) {
278 BFreeBox_t& b = * (BFreeBox_t*) bi();
279 for (Int_t i = 0; i < 8; ++i)
280 BBoxCheckPoint(b.fVertices[i]);
281 }
282 break;
283 }
284
286 {
287 while (bi.next()) {
289 BBoxCheckPoint(b.fX, b.fY, b.fZ);
290 BBoxCheckPoint(b.fX + b.fW, b.fY + b.fH , b.fZ + b.fD);
291 }
292 break;
293 }
294
295 case kBT_Instanced:
296 {
297 while (bi.next()) {
298 Instanced_t& b = * (Instanced_t*) bi();
299 BBoxCheckPoint(b.fX, b.fY, b.fZ);
300 BBoxCheckPoint(b.fX + fDefWidth, b.fY + fDefHeight , b.fZ + fDefDepth);
301 }
302 break;
303 }
304
306 {
307 while (bi.next()) {
309 float* a = b.fMat;
310 BBoxCheckPoint(a[12], a[13], a[14]);
311 }
312 break;
313 }
314
315 default:
316 {
317 throw(eH + "unsupported box-type.");
318 }
319
320 } // end switch box-type
321}
322
323////////////////////////////////////////////////////////////////////////////////
324/// Fill core part of JSON representation.
325
326Int_t REveBoxSet::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
327{
328 j["boxType"] = int(fBoxType);
329 j["shapeType"] = int(fShapeType);
330 if (fShapeType == kCone)
331 {
332 j["coneCap"] = fDrawConeCap;
333 }
334
335
336 j["instanced"] = Instanced();
337 if (Instanced())
338 {
339 int N = fPlex.N();
340 int N_tex = 0;
341 std::string instanceFlag;
342 switch (fBoxType)
343 {
344 case kBT_Instanced:
345 instanceFlag = "FixedDimension";
346 N_tex = N;
347 break;
349 instanceFlag = "ScalePerDigit";
350 N_tex = 2*N;
351 break;
353 instanceFlag = "Mat4Trans";
354 N_tex = 4*N;
355 break;
356 default:
357 std::cout << "Ereor:: Unhandled instanced case\n";
358 }
359
361
362 j["N"] = N;
363 j["texX"] = fTexX;
364 j["texY"] = fTexY;
365 j["instanceFlag"] = instanceFlag;
366 j["defWidth"] = fDefWidth;
367 j["defHeight"] = fDefHeight;
368 j["defDepth"] = fDefDepth;
369
370 // std::cout << "TEXTURE SIZE X " << fTexX << "\n";
371 }
372
373 // AMT:: the base class WroteCoreJson needs to be called after
374 // setting the texture value
375 Int_t ret = REveDigitSet::WriteCoreJson(j, rnr_offset);
376 return ret;
377}
378
379////////////////////////////////////////////////////////////////////////////////
380/// Creates 3D point array for rendering.
381
383{
384 fRenderData = std::make_unique<REveRenderData>("makeBoxSet", fPlex.Size() * 24, 0, fPlex.Size());
385
387 while (bi.next()) {
389 if (IsDigitVisible(b)) {
391 if (fSingleColor == false) {
392
393 if (fValueIsColor) {
394 fRenderData->PushI(int(b->fValue));
395 } else {
396 UChar_t c[4] = {0, 0, 0, 0};
398
399 int value = c[0] + c[1] * 256 + c[2] * 256 * 256;
400 // printf("box val [%d] values (%d, %d, %d) -> int <%d>\n", b.fValue, c[0], c[1], c[2], value);
401 fRenderData->PushI(value);
402 }
403 }
404 }
405 }
406 if (Instanced()) {
407 // printf(" >>> resize render data %d \n", 4 * fTexX * fTexY);
408 fRenderData->ResizeV(4 * fTexX * fTexY);
409 }
410}
411
412////////////////////////////////////////////////////////////////////////////////
413/// Get int value for color. Used for case of instancing.
414///
416{
417 if (fSingleColor == false) {
418 if (fValueIsColor) {
419 UChar_t* c = (UChar_t*) & digi.fValue;
420 return (c[0] << 16) + (c[1] << 8) + c[2];
421 } else {
422 // printf("palette\n");
423 UChar_t c[4] = {0, 0, 0, 0};
425 return (c[0] << 16) + (c[1] << 8) + c[2];
426 }
427 }
428 // printf("main color %d\n", GetMainColor());
429 UChar_t c[4] = {0, 0, 0, 0};
431 // printf("rgb %d %d %d\n", c[0], c[1], c[2]);
432 return (c[0] << 16) + (c[1] << 8) + c[2]; // AMT perhaps this can be ignored
433}
434
436{
437 uint32_t c = GetColorFromDigit(digit);
438 // this line required to avoid strict-aliasing rules warning
439 auto pc = (float *) &c;
440 return *pc;
441}
442
443
444////////////////////////////////////////////////////////////////////////////////
445/// Write shape data for different cases
446///
448{
449 switch (fBoxType) {
452 // vertices
453 for (int c = 0; c < 8; c++) {
454 for (int j = 0; j < 3; j++)
455 fRenderData->PushV(b.fVertices[c][j]);
456 }
457 break;
458 }
459
462 // position
463 fRenderData->PushV(b.fX, b.fY, b.fZ);
464 fRenderData->PushV(GetColorFromDigitAsFloat(b)); // color ?
465 fRenderData->PushV(b.fW, b.fH, b.fD);
466 fRenderData->PushV(2.f); // trasp ?
467 break;
468 }
470 Instanced_t &b =(Instanced_t &)(digit);
471 // position
472 fRenderData->PushV(b.fX, b.fY, b.fZ);
473 fRenderData->PushV(GetColorFromDigitAsFloat(b)); // color ?
474 fRenderData->PushV(2.f); // trasp ?
475 break;
476 }
479 float* a = b.fMat;
480 fRenderData->PushV(a[12], a[13], a[14]);
482 // write the first three columns
483 for (int i = 0; i < 12; i++) {
484 fRenderData->PushV(a[i]);
485 }
486 break;
487 }
488
489 default: assert(false && "REveBoxSet::BuildRenderData only kBT_FreeBox type supported");
490 }
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Fill the structure with a random set of boxes.
495
497{
499 TRandom rnd(0);
500 const Float_t origin = 10, size = 2;
501 Int_t color;
502 for(Int_t i=0; i<nboxes; ++i)
503 {
504 AddInstanceScaled(origin * rnd.Uniform(-1, 1),
505 origin * rnd.Uniform(-1, 1),
506 origin * rnd.Uniform(-1, 1),
507 size * rnd.Uniform(0.1, 1),
508 size * rnd.Uniform(0.1, 1),
509 size * rnd.Uniform(0.1, 1));
510
511 REveUtil::ColorFromIdx(rnd.Integer(256), (UChar_t*)&color);
512 DigitValue(color);
513 }
514}
515
516////////////////////////////////////////////////////////////////////////////////
517/// Use instancing in RenderCore.
518
520{
521 return gEve->IsRCore() && (fBoxType != kBT_FreeBox);
522}
523
524
525/*
526////////////////////////////////////////////////////////////////////////////////
527/// Set DigitShape
528
529bool REveBoxSet::SetDigitShape(const std::vector<float>& vrtBuff, const std::vector<int>& idxBuff)
530{
531 fGeoShape.v = v;
532
533}
534*/
#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
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned char UChar_t
Definition RtypesCore.h:38
constexpr Int_t kMinInt
Definition RtypesCore.h:113
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint angle
void AddInstanceMat4(const Float_t *mat4)
Create shape with arbitrary transformtaion.
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).
Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override
Fill core part of JSON representation.
void BuildRenderData() override
Creates 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 AddInstanceScaled(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d)
Create a new axis-aligned box from at a given position and with specified dimensions.
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,...
unsigned int GetColorFromDigit(REveDigitSet::DigitBase_t &digit)
Get int value for color.
float GetColorFromDigitAsFloat(REveDigitSet::DigitBase_t &digit)
void WriteShapeData(REveDigitSet::DigitBase_t &digit)
Write shape data for different cases.
void AddFreeBox(const Float_t *verts)
Create a new box from a set of 8 vertices.
static Int_t SizeofAtom(EBoxType_e bt)
Return size of data-structure describing a box of type bt.
bool Instanced()
Use instancing in RenderCore.
void AddInstance(Float_t a, Float_t b, Float_t c)
Create a new axis-aligned box from at a given position.
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.
bool IsDigitVisible(const DigitBase_t *) const
Utility function for maping digit idx with visible shape idx.
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.
virtual Color_t GetMainColor() const
REveException Exception-type thrown by Eve classes.
Definition REveTypes.hxx:41
const UChar_t * ColorFromValue(Int_t val) const
static void CalcTextureSize(int nel, int align, int &sx, int &sy)
Calculate texture dimensions to hold nel elements with given alignment on x axis.
static void CheckAndFixBoxOrientationFv(Float_t box[8][3])
Make sure box orientation is consistent with standard arrangement.
void RotatePF(Int_t i1, Int_t i2, Double_t amount)
Rotate in parent frame. Does optimised version of MultLeft.
void RotateLF(Int_t i1, Int_t i2, Double_t amount)
Rotate in local frame. Does optimised version of MultRight.
void SetScale(Double_t sx, Double_t sy, Double_t sz)
Set scaling.
void SetPos(Double_t x, Double_t y, Double_t z)
Set position (base-vec 4).
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:118
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition TAttBBox.h:69
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
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:682
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition TRandom.cxx:361
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
R__EXTERN REveManager * gEve
TMath.
Definition TMathBase.h:35
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:79