Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
viewer3DLocal.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_gl
3/// Demonstrates 3D viewer architecture TVirtualViewer3D and TBuffer3D in the local frame.
4///
5/// Here each shape is described in a TBuffer3D class,
6/// with a suitible translation matrix to place each instance
7/// NOTE: to be executed via .x viewer3DLocal.C+
8///
9/// NOTE: We don't implement raw tesselation of sphere - hence this will
10/// not appear in viewers which don't support directly (non-OpenGL)
11/// Shows that viewers can at least deal gracefully with these cases
12///
13/// Our abstract base shape class.
14///
15/// As we overload TObject::Paint which is called directly from compiled
16/// code, this script must also be compiled to work correctly.
17///
18/// ~~~{.cpp}
19/// #if defined(__CINT__) && !defined(__MAKECINT__)
20/// {
21/// gSystem->CompileMacro("viewer3DLocal.C");
22/// viewer3DLocal();
23/// }
24/// #else
25/// ~~~
26///
27/// \macro_code
28///
29/// \author Richard Maunder
30
31#include "TVirtualViewer3D.h"
32#include "TBuffer3D.h"
33#include "TBuffer3DTypes.h"
34
35#include "TObject.h"
36#include "TVirtualPad.h"
37#include "TAtt3D.h"
38
39#include <vector>
40
41class Shape : public TObject {
42public:
43 Shape(Int_t color, Double_t x, Double_t y, Double_t z);
44 ~Shape() override{};
45 virtual TBuffer3D &GetBuffer3D(UInt_t reqSections) = 0;
46
47protected:
48 Double_t fX, fY, fZ; // Origin
49 Int_t fColor;
50
51 ClassDefOverride(Shape, 0);
52};
53
54
55Shape::Shape(Int_t color, Double_t x, Double_t y, Double_t z) : fX(x), fY(y), fZ(z), fColor(color) {}
56
57class Sphere : public Shape {
58public:
59 Sphere(Int_t color, Double_t x, Double_t y, Double_t z, Double_t radius);
60 ~Sphere() override{};
61
62 TBuffer3D &GetBuffer3D(UInt_t reqSections) override;
63
64private:
65 Double_t fRadius;
66
67 ClassDefOverride(Sphere, 0);
68};
69
70
71Sphere::Sphere(Int_t color, Double_t x, Double_t y, Double_t z, Double_t radius)
72 : Shape(color, x, y, z), fRadius(radius)
73{
74}
75
76TBuffer3D &Sphere::GetBuffer3D(UInt_t reqSections)
77{
78 static TBuffer3DSphere buffer;
79
80 // Complete kCore section - this could be moved to Shape base class
82 buffer.ClearSectionsValid();
83 buffer.fID = this;
84 buffer.fColor = fColor; // Color index - see gROOT->GetColor()
85 buffer.fTransparency = 0; // Transparency 0 (opaque) - 100 (fully transparent)
86
87 // Complete local/master transformation matrix - simple x/y/z
88 // translation. Easiest way to set identity then override the
89 // translation components
91 buffer.fLocalMaster[12] = fX;
92 buffer.fLocalMaster[13] = fY;
93 buffer.fLocalMaster[14] = fZ;
94 buffer.fLocalFrame = kTRUE; // Local frame
95
96 buffer.fReflection = kFALSE;
98 }
99 // Complete kBoundingBox section
101 Double_t origin[3] = {0.0, 0.0, 0.0};
102 Double_t halfLength[3] = {fRadius, fRadius, fRadius};
105 }
106 // Complete kShapeSpecific section
108 buffer.fRadiusOuter = fRadius;
109 buffer.fRadiusInner = 0.0;
110 buffer.fThetaMin = 0.0;
111 buffer.fThetaMax = 180.0;
112 buffer.fPhiMin = 0.0;
113 buffer.fPhiMax = 360.0;
115 }
116 // We don't implement raw tesselation of sphere - hence this will
117 // not appear in viewers which don't support directly (non-OpenGL)
118 // Complete kRawSizes section
120 // buffer.SetSectionsValid(TBuffer3D::kRawSizes);
121 }
122 // Complete kRaw section
124 // buffer.SetSectionsValid(TBuffer3D::kRaw);
125 }
126
127 return buffer;
128}
129
130class Box : public Shape {
131public:
133 ~Box() override{};
134
135 TBuffer3D &GetBuffer3D(UInt_t reqSections) override;
136
137private:
138 Double_t fDX, fDY, fDZ; // Half lengths
139
140 ClassDefOverride(Box, 0);
141};
142
143
145 : Shape(color, x, y, z), fDX(dX), fDY(dY), fDZ(dZ)
146{
147}
148
149TBuffer3D &Box::GetBuffer3D(UInt_t reqSections)
150{
151 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
152
153 // Complete kCore section - this could be moved to Shape base class
155 buffer.ClearSectionsValid();
156 buffer.fID = this;
157 buffer.fColor = fColor; // Color index - see gROOT->GetColor()
158 buffer.fTransparency = 0; // Transparency 0 (opaque) - 100 (fully transparent)
159
160 // Complete local/master transformation matrix - simple x/y/z
161 // translation. Easiest way to set identity then override the
162 // translation components
163 buffer.SetLocalMasterIdentity();
164 buffer.fLocalMaster[12] = fX;
165 buffer.fLocalMaster[13] = fY;
166 buffer.fLocalMaster[14] = fZ;
167 buffer.fLocalFrame = kTRUE; // Local frame
168
169 buffer.fReflection = kFALSE;
171 }
172 // Complete kBoundingBox section
174 Double_t origin[3] = {fX, fY, fZ};
175 Double_t halfLength[3] = {fDX, fDY, fDZ};
178 }
179 // No kShapeSpecific section
180
181 // Complete kRawSizes section
183 buffer.SetRawSizes(8, 3 * 8, 12, 3 * 12, 6, 6 * 6);
185 }
186 // Complete kRaw section
188 // Points (8)
189 // 3 components: x,y,z
190 buffer.fPnts[0] = fX - fDX;
191 buffer.fPnts[1] = fY - fDY;
192 buffer.fPnts[2] = fZ - fDZ; // 0
193 buffer.fPnts[3] = fX + fDX;
194 buffer.fPnts[4] = fY - fDY;
195 buffer.fPnts[5] = fZ - fDZ; // 1
196 buffer.fPnts[6] = fX + fDX;
197 buffer.fPnts[7] = fY + fDY;
198 buffer.fPnts[8] = fZ - fDZ; // 2
199 buffer.fPnts[9] = fX - fDX;
200 buffer.fPnts[10] = fY + fDY;
201 buffer.fPnts[11] = fZ - fDZ; // 3
202 buffer.fPnts[12] = fX - fDX;
203 buffer.fPnts[13] = fY - fDY;
204 buffer.fPnts[14] = fZ + fDZ; // 4
205 buffer.fPnts[15] = fX + fDX;
206 buffer.fPnts[16] = fY - fDY;
207 buffer.fPnts[17] = fZ + fDZ; // 5
208 buffer.fPnts[18] = fX + fDX;
209 buffer.fPnts[19] = fY + fDY;
210 buffer.fPnts[20] = fZ + fDZ; // 6
211 buffer.fPnts[21] = fX - fDX;
212 buffer.fPnts[22] = fY + fDY;
213 buffer.fPnts[23] = fZ + fDZ; // 7
214
215 // Segments (12)
216 // 3 components: segment color(ignored), start point index, end point index
217 // Indexes reference the above points
218 buffer.fSegs[0] = fColor;
219 buffer.fSegs[1] = 0;
220 buffer.fSegs[2] = 1; // 0
221 buffer.fSegs[3] = fColor;
222 buffer.fSegs[4] = 1;
223 buffer.fSegs[5] = 2; // 1
224 buffer.fSegs[6] = fColor;
225 buffer.fSegs[7] = 2;
226 buffer.fSegs[8] = 3; // 2
227 buffer.fSegs[9] = fColor;
228 buffer.fSegs[10] = 3;
229 buffer.fSegs[11] = 0; // 3
230 buffer.fSegs[12] = fColor;
231 buffer.fSegs[13] = 4;
232 buffer.fSegs[14] = 5; // 4
233 buffer.fSegs[15] = fColor;
234 buffer.fSegs[16] = 5;
235 buffer.fSegs[17] = 6; // 5
236 buffer.fSegs[18] = fColor;
237 buffer.fSegs[19] = 6;
238 buffer.fSegs[20] = 7; // 6
239 buffer.fSegs[21] = fColor;
240 buffer.fSegs[22] = 7;
241 buffer.fSegs[23] = 4; // 7
242 buffer.fSegs[24] = fColor;
243 buffer.fSegs[25] = 0;
244 buffer.fSegs[26] = 4; // 8
245 buffer.fSegs[27] = fColor;
246 buffer.fSegs[28] = 1;
247 buffer.fSegs[29] = 5; // 9
248 buffer.fSegs[30] = fColor;
249 buffer.fSegs[31] = 2;
250 buffer.fSegs[32] = 6; // 10
251 buffer.fSegs[33] = fColor;
252 buffer.fSegs[34] = 3;
253 buffer.fSegs[35] = 7; // 11
254
255 // Polygons (6)
256 // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
257 // seg1, seg2 .... segn index
258 // Segments indexes refer to the above 12 segments
259 // Here n=4 - each polygon defines a rectangle - 4 sides.
260 buffer.fPols[0] = fColor;
261 buffer.fPols[1] = 4;
262 buffer.fPols[2] = 8; // 0
263 buffer.fPols[3] = 4;
264 buffer.fPols[4] = 9;
265 buffer.fPols[5] = 0;
266 buffer.fPols[6] = fColor;
267 buffer.fPols[7] = 4;
268 buffer.fPols[8] = 9; // 1
269 buffer.fPols[9] = 5;
270 buffer.fPols[10] = 10;
271 buffer.fPols[11] = 1;
272 buffer.fPols[12] = fColor;
273 buffer.fPols[13] = 4;
274 buffer.fPols[14] = 10; // 2
275 buffer.fPols[15] = 6;
276 buffer.fPols[16] = 11;
277 buffer.fPols[17] = 2;
278 buffer.fPols[18] = fColor;
279 buffer.fPols[19] = 4;
280 buffer.fPols[20] = 11; // 3
281 buffer.fPols[21] = 7;
282 buffer.fPols[22] = 8;
283 buffer.fPols[23] = 3;
284 buffer.fPols[24] = fColor;
285 buffer.fPols[25] = 4;
286 buffer.fPols[26] = 1; // 4
287 buffer.fPols[27] = 2;
288 buffer.fPols[28] = 3;
289 buffer.fPols[29] = 0;
290 buffer.fPols[30] = fColor;
291 buffer.fPols[31] = 4;
292 buffer.fPols[32] = 7; // 5
293 buffer.fPols[33] = 6;
294 buffer.fPols[34] = 5;
295 buffer.fPols[35] = 4;
296
298 }
299
300 return buffer;
301}
302
303class SBPyramid : public Shape {
304public:
306 ~SBPyramid() override{};
307
308 TBuffer3D &GetBuffer3D(UInt_t reqSections) override;
309
310private:
311 Double_t fDX, fDY, fDZ; // Base half lengths dX,dY
312 // Pyr. height dZ
313
315};
316
317
318SBPyramid::SBPyramid(Int_t color, Double_t x, Double_t y, Double_t z, Double_t dX, Double_t dY, Double_t dZ)
319 : Shape(color, x, y, z), fDX(dX), fDY(dY), fDZ(dZ)
320{
321}
322
323TBuffer3D &SBPyramid::GetBuffer3D(UInt_t reqSections)
324{
325 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
326
327 // Complete kCore section
329 buffer.ClearSectionsValid();
330 buffer.fID = this;
331 buffer.fColor = fColor; // Color index - see gROOT->GetColor()
332 buffer.fTransparency = 0; // Transparency 0 (opaque) - 100 (fully transparent)
333
334 // Complete local/master transformation matrix - simple x/y/z
335 // translation. Easiest way to set identity then override the
336 // translation components
337 buffer.SetLocalMasterIdentity();
338 buffer.fLocalMaster[12] = fX;
339 buffer.fLocalMaster[13] = fY;
340 buffer.fLocalMaster[14] = fZ;
341 buffer.fLocalFrame = kTRUE; // Local frame
342
343 buffer.fReflection = kFALSE;
345 }
346 // Complete kBoundingBox section
348 Double_t halfLength[3] = {fDX, fDY, fDZ / 2.0};
349 Double_t origin[3] = {fX, fY, fZ + halfLength[2]};
352 }
353 // No kShapeSpecific section
354
355 // Complete kRawSizes section
357 buffer.SetRawSizes(5, 3 * 5, 8, 3 * 8, 5, 6 + 4 * 5);
359 }
360 // Complete kRaw section
362 // Points (5)
363 // 3 components: x,y,z
364 buffer.fPnts[0] = fX - fDX;
365 buffer.fPnts[1] = fY - fDY;
366 buffer.fPnts[2] = fZ; // 0
367 buffer.fPnts[3] = fX + fDX;
368 buffer.fPnts[4] = fY - fDY;
369 buffer.fPnts[5] = fZ; // 1
370 buffer.fPnts[6] = fX + fDX;
371 buffer.fPnts[7] = fY + fDY;
372 buffer.fPnts[8] = fZ; // 2
373 buffer.fPnts[9] = fX - fDX;
374 buffer.fPnts[10] = fY + fDY;
375 buffer.fPnts[11] = fZ; // 3
376 buffer.fPnts[12] = fX;
377 buffer.fPnts[13] = fY;
378 buffer.fPnts[14] = fZ + fDZ; // 4 (pyr top point)
379
380 // Segments (8)
381 // 3 components: segment color(ignored), start point index, end point index
382 // Indexes reference the above points
383
384 buffer.fSegs[0] = fColor;
385 buffer.fSegs[1] = 0;
386 buffer.fSegs[2] = 1; // 0 base
387 buffer.fSegs[3] = fColor;
388 buffer.fSegs[4] = 1;
389 buffer.fSegs[5] = 2; // 1 base
390 buffer.fSegs[6] = fColor;
391 buffer.fSegs[7] = 2;
392 buffer.fSegs[8] = 3; // 2 base
393 buffer.fSegs[9] = fColor;
394 buffer.fSegs[10] = 3;
395 buffer.fSegs[11] = 0; // 3 base
396 buffer.fSegs[12] = fColor;
397 buffer.fSegs[13] = 0;
398 buffer.fSegs[14] = 4; // 4 side
399 buffer.fSegs[15] = fColor;
400 buffer.fSegs[16] = 1;
401 buffer.fSegs[17] = 4; // 5 side
402 buffer.fSegs[18] = fColor;
403 buffer.fSegs[19] = 2;
404 buffer.fSegs[20] = 4; // 6 side
405 buffer.fSegs[21] = fColor;
406 buffer.fSegs[22] = 3;
407 buffer.fSegs[23] = 4; // 7 side
408
409 // Polygons (6)
410 // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
411 // seg1, seg2 .... segn index
412 // Segments indexes refer to the above 12 segments
413 // Here n=4 - each polygon defines a rectangle - 4 sides.
414 buffer.fPols[0] = fColor;
415 buffer.fPols[1] = 4;
416 buffer.fPols[2] = 0; // base
417 buffer.fPols[3] = 1;
418 buffer.fPols[4] = 2;
419 buffer.fPols[5] = 3;
420
421 buffer.fPols[6] = fColor;
422 buffer.fPols[7] = 3;
423 buffer.fPols[8] = 0; // side 0
424 buffer.fPols[9] = 4;
425 buffer.fPols[10] = 5;
426 buffer.fPols[11] = fColor;
427 buffer.fPols[12] = 3;
428 buffer.fPols[13] = 1; // side 1
429 buffer.fPols[14] = 5;
430 buffer.fPols[15] = 6;
431 buffer.fPols[16] = fColor;
432 buffer.fPols[17] = 3;
433 buffer.fPols[18] = 2; // side 2
434 buffer.fPols[19] = 6;
435 buffer.fPols[20] = 7;
436 buffer.fPols[21] = fColor;
437 buffer.fPols[22] = 3;
438 buffer.fPols[23] = 3; // side 3
439 buffer.fPols[24] = 7;
440 buffer.fPols[25] = 4;
441
443 }
444
445 return buffer;
446}
447
448class MyGeom : public TObject, public TAtt3D {
449public:
450 MyGeom();
451 ~MyGeom() override;
452
453 void Draw(Option_t *option) override;
454 void Paint(Option_t *option) override;
455
456private:
457 std::vector<Shape *> fShapes;
458
460};
461
462
463MyGeom::MyGeom()
464{
465 // Create our simple geometry - sphere, couple of boxes
466 // and a square base pyramid
467 Shape *aShape;
468 aShape = new Sphere(kYellow, 80.0, 60.0, 120.0, 10.0);
469 fShapes.push_back(aShape);
470 aShape = new Box(kRed, 0.0, 0.0, 0.0, 20.0, 20.0, 20.0);
471 fShapes.push_back(aShape);
472 aShape = new Box(kBlue, 50.0, 100.0, 200.0, 5.0, 10.0, 15.0);
473 fShapes.push_back(aShape);
474 aShape = new SBPyramid(kGreen, 20.0, 25.0, 45.0, 30.0, 30.0, 90.0);
475 fShapes.push_back(aShape);
476}
477
478MyGeom::~MyGeom()
479{
480 // Clear out fShapes
481}
482
483void MyGeom::Draw(Option_t *option)
484{
485 TObject::Draw(option);
486
487 // Ask pad to create 3D viewer of type 'option'
488 gPad->GetViewer3D(option);
489}
490
491void MyGeom::Paint(Option_t * /*option*/)
492{
493 TVirtualViewer3D *viewer = gPad->GetViewer3D();
494
495 // If MyGeom derives from TAtt3D then pad will recognise
496 // that the object it is asking to paint is 3D, and open/close
497 // the scene for us. If not Open/Close are required
498 // viewer->BeginScene();
499
500 // We are working in the master frame - so we don't bother
501 // to ask the viewer if it prefers local. Viewer's must
502 // always support master frame as minimum. c.f. with
503 // viewer3DLocal.C
504 std::vector<Shape *>::const_iterator ShapeIt = fShapes.begin();
505 Shape *shape;
506 while (ShapeIt != fShapes.end()) {
507 shape = *ShapeIt;
508
510 TBuffer3D &buffer = shape->GetBuffer3D(reqSections);
511 reqSections = viewer->AddObject(buffer);
512
514 shape->GetBuffer3D(reqSections);
515 viewer->AddObject(buffer);
516 }
517 ShapeIt++;
518 }
519 // Not required as we are TAtt3D subclass
520 // viewer->EndScene();
521}
522
523void viewer3DLocal()
524{
525 printf("\n\nviewer3DLocal: This frame demonstates local frame use of 3D viewer architecture.\n");
526 printf("Creates sphere, two boxes and a square based pyramid, described in local frame.\n");
527 printf("We do not implement raw tesselation of sphere - hence will not appear in viewers\n");
528 printf("which do not support in natively (non-GL viewer).\n\n");
529
530 // macro uses GL features not supported in web graphics
531 gROOT->SetWebDisplay("off");
532
533 MyGeom *myGeom = new MyGeom;
534 myGeom->Draw("ogl");
535}
536
537// #endif
#define d(i)
Definition RSha256.hxx:102
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
@ kRed
Definition Rtypes.h:67
@ kGreen
Definition Rtypes.h:67
@ kBlue
Definition Rtypes.h:67
@ kYellow
Definition Rtypes.h:67
#define ClassDefOverride(name, id)
Definition Rtypes.h:348
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t option
#define gROOT
Definition TROOT.h:411
#define gPad
const_iterator begin() const
const_iterator end() const
Use this attribute class when an object should have 3D capabilities.
Definition TAtt3D.h:19
Sphere description class - see TBuffer3DTypes for producer classes Supports hollow and cut spheres.
Definition TBuffer3D.h:130
Double_t fRadiusInner
Definition TBuffer3D.h:144
Double_t fThetaMin
Definition TBuffer3D.h:146
Double_t fPhiMin
Definition TBuffer3D.h:148
Double_t fThetaMax
Definition TBuffer3D.h:147
Double_t fRadiusOuter
Definition TBuffer3D.h:145
Double_t fPhiMax
Definition TBuffer3D.h:149
Generic 3D primitive description class.
Definition TBuffer3D.h:18
void SetLocalMasterIdentity()
Set kRaw tessellation section of buffer with supplied sizes.
Int_t * fPols
Definition TBuffer3D.h:115
@ kBoundingBox
Definition TBuffer3D.h:51
@ kShapeSpecific
Definition TBuffer3D.h:52
Double_t fLocalMaster[16]
Definition TBuffer3D.h:93
void ClearSectionsValid()
Clear any sections marked valid.
void SetSectionsValid(UInt_t mask)
Definition TBuffer3D.h:65
Int_t * fSegs
Definition TBuffer3D.h:114
Bool_t fLocalFrame
Definition TBuffer3D.h:90
Int_t fColor
Definition TBuffer3D.h:88
Short_t fTransparency
Definition TBuffer3D.h:89
void SetAABoundingBox(const Double_t origin[3], const Double_t halfLengths[3])
Set fBBVertex in kBoundingBox section to a axis aligned (local) BB using supplied origin and box half...
Bool_t fReflection
Definition TBuffer3D.h:91
TObject * fID
Definition TBuffer3D.h:87
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
Double_t * fPnts
Definition TBuffer3D.h:113
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:293
Abstract 3D shapes viewer.
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
th1 Draw()