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