Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
viewer3DMaster.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_gl
3/// Demonstrates 3D viewer architecture TVirtualViewer3D and TBuffer3D in the master frame.
4/// Here each shape is described directly in a TBuffer3D
5/// class, with identity translation matrix c.f. viewer3DLocal.C
6///
7/// Our abstract base shape class.
8///
9/// As we overload TObject::Paint which is called directly from compiled
10/// code, this script must also be compiled to work correctly.
11///
12/// \macro_code
13///
14/// \author Richard Maunder
15
16#include "TVirtualViewer3D.h"
17#include "TBuffer3D.h"
18#include "TBuffer3DTypes.h"
19
20#include "TObject.h"
21#include "TVirtualPad.h"
22#include "TAtt3D.h"
23
24#include <vector>
25
26class Shape : public TObject {
27public:
28 Shape(Int_t color, Double_t x, Double_t y, Double_t z);
29 ~Shape() override{};
30 virtual TBuffer3D &GetBuffer3D(UInt_t reqSections) = 0;
31
32protected:
33 Double_t fX, fY, fZ; // Origin
34 Int_t fColor;
35
36 ClassDefOverride(Shape, 0);
37};
38
39
40Shape::Shape(Int_t color, Double_t x, Double_t y, Double_t z) : fX(x), fY(y), fZ(z), fColor(color) {}
41
42class Box : public Shape {
43public:
45 ~Box() override{};
46
47 TBuffer3D &GetBuffer3D(UInt_t reqSections) override;
48
49private:
50 Double_t fDX, fDY, fDZ; // Half lengths
51
52 ClassDefOverride(Box, 0);
53};
54
55
57 : Shape(color, x, y, z), fDX(dX), fDY(dY), fDZ(dZ)
58{
59}
60
61TBuffer3D &Box::GetBuffer3D(UInt_t reqSections)
62{
64
65 // Complete kCore section - this could be moved to Shape base class
67 buffer.ClearSectionsValid();
68 buffer.fID = this;
69 buffer.fColor = fColor; // Color index - see gROOT->GetColor()
70 buffer.fTransparency = 0; // Transparency 0 (opaque) - 100 (fully transparent)
71 buffer.fLocalFrame = kFALSE;
72 buffer.SetLocalMasterIdentity();
73 buffer.fReflection = kFALSE;
74 buffer.SetSectionsValid(TBuffer3D::kCore);
75 }
76 // Complete kBoundingBox section
78 Double_t origin[3] = {fX, fY, fZ};
79 Double_t halfLength[3] = {fDX, fDY, fDZ};
80 buffer.SetAABoundingBox(origin, halfLength);
81 buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
82 }
83 // No kShapeSpecific section
84
85 // Complete kRawSizes section
87 buffer.SetRawSizes(8, 3 * 8, 12, 3 * 12, 6, 6 * 6);
88 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
89 }
90 // Complete kRaw section
92 // Points (8)
93 // 3 components: x,y,z
94 buffer.fPnts[0] = fX - fDX;
95 buffer.fPnts[1] = fY - fDY;
96 buffer.fPnts[2] = fZ - fDZ; // 0
97 buffer.fPnts[3] = fX + fDX;
98 buffer.fPnts[4] = fY - fDY;
99 buffer.fPnts[5] = fZ - fDZ; // 1
100 buffer.fPnts[6] = fX + fDX;
101 buffer.fPnts[7] = fY + fDY;
102 buffer.fPnts[8] = fZ - fDZ; // 2
103 buffer.fPnts[9] = fX - fDX;
104 buffer.fPnts[10] = fY + fDY;
105 buffer.fPnts[11] = fZ - fDZ; // 3
106 buffer.fPnts[12] = fX - fDX;
107 buffer.fPnts[13] = fY - fDY;
108 buffer.fPnts[14] = fZ + fDZ; // 4
109 buffer.fPnts[15] = fX + fDX;
110 buffer.fPnts[16] = fY - fDY;
111 buffer.fPnts[17] = fZ + fDZ; // 5
112 buffer.fPnts[18] = fX + fDX;
113 buffer.fPnts[19] = fY + fDY;
114 buffer.fPnts[20] = fZ + fDZ; // 6
115 buffer.fPnts[21] = fX - fDX;
116 buffer.fPnts[22] = fY + fDY;
117 buffer.fPnts[23] = fZ + fDZ; // 7
118
119 // Segments (12)
120 // 3 components: segment color(ignored), start point index, end point index
121 // Indexes reference the above points
122 buffer.fSegs[0] = fColor;
123 buffer.fSegs[1] = 0;
124 buffer.fSegs[2] = 1; // 0
125 buffer.fSegs[3] = fColor;
126 buffer.fSegs[4] = 1;
127 buffer.fSegs[5] = 2; // 1
128 buffer.fSegs[6] = fColor;
129 buffer.fSegs[7] = 2;
130 buffer.fSegs[8] = 3; // 2
131 buffer.fSegs[9] = fColor;
132 buffer.fSegs[10] = 3;
133 buffer.fSegs[11] = 0; // 3
134 buffer.fSegs[12] = fColor;
135 buffer.fSegs[13] = 4;
136 buffer.fSegs[14] = 5; // 4
137 buffer.fSegs[15] = fColor;
138 buffer.fSegs[16] = 5;
139 buffer.fSegs[17] = 6; // 5
140 buffer.fSegs[18] = fColor;
141 buffer.fSegs[19] = 6;
142 buffer.fSegs[20] = 7; // 6
143 buffer.fSegs[21] = fColor;
144 buffer.fSegs[22] = 7;
145 buffer.fSegs[23] = 4; // 7
146 buffer.fSegs[24] = fColor;
147 buffer.fSegs[25] = 0;
148 buffer.fSegs[26] = 4; // 8
149 buffer.fSegs[27] = fColor;
150 buffer.fSegs[28] = 1;
151 buffer.fSegs[29] = 5; // 9
152 buffer.fSegs[30] = fColor;
153 buffer.fSegs[31] = 2;
154 buffer.fSegs[32] = 6; // 10
155 buffer.fSegs[33] = fColor;
156 buffer.fSegs[34] = 3;
157 buffer.fSegs[35] = 7; // 11
158
159 // Polygons (6)
160 // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
161 // seg1, seg2 .... segn index
162 // Segments indexes refer to the above 12 segments
163 // Here n=4 - each polygon defines a rectangle - 4 sides.
164 buffer.fPols[0] = fColor;
165 buffer.fPols[1] = 4;
166 buffer.fPols[2] = 8; // 0
167 buffer.fPols[3] = 4;
168 buffer.fPols[4] = 9;
169 buffer.fPols[5] = 0;
170 buffer.fPols[6] = fColor;
171 buffer.fPols[7] = 4;
172 buffer.fPols[8] = 9; // 1
173 buffer.fPols[9] = 5;
174 buffer.fPols[10] = 10;
175 buffer.fPols[11] = 1;
176 buffer.fPols[12] = fColor;
177 buffer.fPols[13] = 4;
178 buffer.fPols[14] = 10; // 2
179 buffer.fPols[15] = 6;
180 buffer.fPols[16] = 11;
181 buffer.fPols[17] = 2;
182 buffer.fPols[18] = fColor;
183 buffer.fPols[19] = 4;
184 buffer.fPols[20] = 11; // 3
185 buffer.fPols[21] = 7;
186 buffer.fPols[22] = 8;
187 buffer.fPols[23] = 3;
188 buffer.fPols[24] = fColor;
189 buffer.fPols[25] = 4;
190 buffer.fPols[26] = 1; // 4
191 buffer.fPols[27] = 2;
192 buffer.fPols[28] = 3;
193 buffer.fPols[29] = 0;
194 buffer.fPols[30] = fColor;
195 buffer.fPols[31] = 4;
196 buffer.fPols[32] = 7; // 5
197 buffer.fPols[33] = 6;
198 buffer.fPols[34] = 5;
199 buffer.fPols[35] = 4;
200
201 buffer.SetSectionsValid(TBuffer3D::kRaw);
202 }
203
204 return buffer;
205}
206
207class SBPyramid : public Shape {
208public:
210 ~SBPyramid() override{};
211
212 TBuffer3D &GetBuffer3D(UInt_t reqSections) override;
213
214private:
215 Double_t fDX, fDY, fDZ; // Base half lengths dX,dY
216 // Pyr. height dZ
217
219};
220
221
222SBPyramid::SBPyramid(Int_t color, Double_t x, Double_t y, Double_t z, Double_t dX, Double_t dY, Double_t dZ)
223 : Shape(color, x, y, z), fDX(dX), fDY(dY), fDZ(dZ)
224{
225}
226
227TBuffer3D &SBPyramid::GetBuffer3D(UInt_t reqSections)
228{
229 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
230
231 // Complete kCore section - this could be moved to Shape base class
233 buffer.ClearSectionsValid();
234 buffer.fID = this;
235 buffer.fColor = fColor; // Color index - see gROOT->GetColor()
236 buffer.fTransparency = 0; // Transparency 0 (opaque) - 100 (fully transparent)
237 buffer.fLocalFrame = kFALSE;
238 buffer.SetLocalMasterIdentity();
239 buffer.fReflection = kFALSE;
240 buffer.SetSectionsValid(TBuffer3D::kCore);
241 }
242 // Complete kBoundingBox section
244 Double_t halfLength[3] = {fDX, fDY, fDZ / 2.0};
245 Double_t origin[3] = {fX, fY, fZ + halfLength[2]};
246 buffer.SetAABoundingBox(origin, halfLength);
247 buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
248 }
249 // No kShapeSpecific section
250
251 // Complete kRawSizes section
253 buffer.SetRawSizes(5, 3 * 5, 8, 3 * 8, 5, 6 + 4 * 5);
254 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
255 }
256 // Complete kRaw section
258 // Points (5)
259 // 3 components: x,y,z
260 buffer.fPnts[0] = fX - fDX;
261 buffer.fPnts[1] = fY - fDY;
262 buffer.fPnts[2] = fZ; // 0
263 buffer.fPnts[3] = fX + fDX;
264 buffer.fPnts[4] = fY - fDY;
265 buffer.fPnts[5] = fZ; // 1
266 buffer.fPnts[6] = fX + fDX;
267 buffer.fPnts[7] = fY + fDY;
268 buffer.fPnts[8] = fZ; // 2
269 buffer.fPnts[9] = fX - fDX;
270 buffer.fPnts[10] = fY + fDY;
271 buffer.fPnts[11] = fZ; // 3
272 buffer.fPnts[12] = fX;
273 buffer.fPnts[13] = fY;
274 buffer.fPnts[14] = fZ + fDZ; // 4 (pyr top point)
275
276 // Segments (8)
277 // 3 components: segment color(ignored), start point index, end point index
278 // Indexes reference the above points
279
280 buffer.fSegs[0] = fColor;
281 buffer.fSegs[1] = 0;
282 buffer.fSegs[2] = 1; // 0 base
283 buffer.fSegs[3] = fColor;
284 buffer.fSegs[4] = 1;
285 buffer.fSegs[5] = 2; // 1 base
286 buffer.fSegs[6] = fColor;
287 buffer.fSegs[7] = 2;
288 buffer.fSegs[8] = 3; // 2 base
289 buffer.fSegs[9] = fColor;
290 buffer.fSegs[10] = 3;
291 buffer.fSegs[11] = 0; // 3 base
292 buffer.fSegs[12] = fColor;
293 buffer.fSegs[13] = 0;
294 buffer.fSegs[14] = 4; // 4 side
295 buffer.fSegs[15] = fColor;
296 buffer.fSegs[16] = 1;
297 buffer.fSegs[17] = 4; // 5 side
298 buffer.fSegs[18] = fColor;
299 buffer.fSegs[19] = 2;
300 buffer.fSegs[20] = 4; // 6 side
301 buffer.fSegs[21] = fColor;
302 buffer.fSegs[22] = 3;
303 buffer.fSegs[23] = 4; // 7 side
304
305 // Polygons (6)
306 // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
307 // seg1, seg2 .... segn index
308 // Segments indexes refer to the above 12 segments
309 // Here n=4 - each polygon defines a rectangle - 4 sides.
310 buffer.fPols[0] = fColor;
311 buffer.fPols[1] = 4;
312 buffer.fPols[2] = 0; // base
313 buffer.fPols[3] = 1;
314 buffer.fPols[4] = 2;
315 buffer.fPols[5] = 3;
316
317 buffer.fPols[6] = fColor;
318 buffer.fPols[7] = 3;
319 buffer.fPols[8] = 0; // side 0
320 buffer.fPols[9] = 4;
321 buffer.fPols[10] = 5;
322 buffer.fPols[11] = fColor;
323 buffer.fPols[12] = 3;
324 buffer.fPols[13] = 1; // side 1
325 buffer.fPols[14] = 5;
326 buffer.fPols[15] = 6;
327 buffer.fPols[16] = fColor;
328 buffer.fPols[17] = 3;
329 buffer.fPols[18] = 2; // side 2
330 buffer.fPols[19] = 6;
331 buffer.fPols[20] = 7;
332 buffer.fPols[21] = fColor;
333 buffer.fPols[22] = 3;
334 buffer.fPols[23] = 3; // side 3
335 buffer.fPols[24] = 7;
336 buffer.fPols[25] = 4;
337
338 buffer.SetSectionsValid(TBuffer3D::kRaw);
339 }
340
341 return buffer;
342}
343
344class MyGeom : public TObject, public TAtt3D {
345public:
346 MyGeom();
347 ~MyGeom() override;
348
349 void Draw(Option_t *option) override;
350 void Paint(Option_t *option) override;
351
352private:
353 std::vector<Shape *> fShapes;
354
356};
357
358
359MyGeom::MyGeom()
360{
361 // Create our simple geometry - couple of boxes
362 // and a square base pyramid
363 Shape *aShape;
364 aShape = new Box(kRed, 0.0, 0.0, 0.0, 20.0, 20.0, 20.0);
365 fShapes.push_back(aShape);
366 aShape = new Box(kBlue, 50.0, 100.0, 200.0, 5.0, 10.0, 15.0);
367 fShapes.push_back(aShape);
368 aShape = new SBPyramid(kGreen, 20.0, 25.0, 45.0, 30.0, 30.0, 90.0);
369 fShapes.push_back(aShape);
370}
371
372MyGeom::~MyGeom()
373{
374 // Clear out fShapes
375}
376
377void MyGeom::Draw(Option_t *option)
378{
379 TObject::Draw(option);
380
381 // Ask pad to create 3D viewer of type 'option'
382 gPad->GetViewer3D(option);
383}
384
385void MyGeom::Paint(Option_t * /*option*/)
386{
387 TVirtualViewer3D *viewer = gPad->GetViewer3D();
388
389 // If MyGeom derives from TAtt3D then pad will recognise
390 // that the object it is asking to paint is 3D, and open/close
391 // the scene for us. If not Open/Close are required
392 // viewer->BeginScene();
393
394 // We are working in the master frame - so we don't bother
395 // to ask the viewer if it prefers local. Viewer's must
396 // always support master frame as minimum. c.f. with
397 // viewer3DLocal.C
398 std::vector<Shape *>::const_iterator ShapeIt = fShapes.begin();
399 Shape *shape;
400 while (ShapeIt != fShapes.end()) {
401 shape = *ShapeIt;
402
404 TBuffer3D &buffer = shape->GetBuffer3D(reqSections);
405 reqSections = viewer->AddObject(buffer);
406
408 shape->GetBuffer3D(reqSections);
409 viewer->AddObject(buffer);
410 }
411 ShapeIt++;
412 }
413 // Not required as we are TAtt3D subclass
414 // viewer->EndScene();
415}
416
417void viewer3DMaster()
418{
419 printf("\n\nviewer3DMaster: This frame demonstates master frame use of 3D viewer architecture.\n");
420 printf("Creates two boxes and a square based pyramid, described in master frame.\n\n");
421
422 // macro uses GL features not supported in web graphics
423 gROOT->SetWebDisplay("off");
424
425 MyGeom *myGeom = new MyGeom;
426 myGeom->Draw("ogl");
427}
#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
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
#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
Generic 3D primitive description class.
Definition TBuffer3D.h:18
@ kBoundingBox
Definition TBuffer3D.h:51
@ kShapeSpecific
Definition TBuffer3D.h:52
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()