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