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