Logo ROOT   6.14/05
Reference Guide
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 
27 class Shape : public TObject
28 {
29 public:
30  Shape(Int_t color, Double_t x, Double_t y, Double_t z);
31  ~Shape() {};
32  virtual TBuffer3D & GetBuffer3D(UInt_t reqSections) = 0;
33 
34 protected:
35  Double_t fX, fY, fZ; // Origin
36  Int_t fColor;
37 
38  ClassDef(Shape,0);
39 };
40 
41 ClassImp(Shape);
42 
43 Shape::Shape(Int_t color, Double_t x, Double_t y, Double_t z) :
44  fX(x), fY(y), fZ(z), fColor(color)
45 {}
46 
47 class Box : public Shape
48 {
49 public:
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() {};
53 
54  virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);
55 
56 private:
57  Double_t fDX, fDY, fDZ; // Half lengths
58 
59  ClassDef(Box,0);
60 };
61 
62 ClassImp(Box);
63 
64 Box::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 
70 TBuffer3D & Box::GetBuffer3D(UInt_t reqSections)
71 {
72  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
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 
152 class SBPyramid : public Shape
153 {
154 public:
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() {};
158 
159  virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);
160 
161 private:
162  Double_t fDX, fDY, fDZ; // Base half lengths dX,dY
163  // Pyr. height dZ
164 
165  ClassDef(SBPyramid,0);
166 };
167 
168 ClassImp(SBPyramid);
169 
170 SBPyramid::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 
176 TBuffer3D & 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 
251 class MyGeom : public TObject, public TAtt3D
252 {
253 public:
254  MyGeom();
255  ~MyGeom();
256 
257  void Draw(Option_t *option);
258  void Paint(Option_t *option);
259 
260 private:
261  std::vector<Shape *> fShapes;
262 
263  ClassDef(MyGeom,0);
264 };
265 
266 ClassImp(MyGeom);
267 
268 MyGeom::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 
281 MyGeom::~MyGeom()
282 {
283  // Clear out fShapes
284 }
285 
286 void MyGeom::Draw(Option_t *option)
287 {
288  TObject::Draw(option);
289 
290  // Ask pad to create 3D viewer of type 'option'
291  gPad->GetViewer3D(option);
292 }
293 
294 void 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 
312  UInt_t reqSections = TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific;
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 
326 void 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 
const char Option_t
Definition: RtypesCore.h:62
Definition: Rtypes.h:59
Use this attribute class when an object should have 3D capabilities.
Definition: TAtt3D.h:19
int Int_t
Definition: RtypesCore.h:41
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:195
Definition: Rtypes.h:59
Double_t x[n]
Definition: legend1.C:17
#define ClassDef(name, id)
Definition: Rtypes.h:320
Abstract 3D shapes viewer.
th1 Draw()
virtual Int_t AddObject(const TBuffer3D &buffer, Bool_t *addChildren=0)=0
unsigned int UInt_t
Definition: RtypesCore.h:42
Generic 3D primitive description class.
Definition: TBuffer3D.h:17
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define d(i)
Definition: RSha256.hxx:102
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
Double_t y[n]
Definition: legend1.C:17
Mother of all ROOT objects.
Definition: TObject.h:37
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
#define gPad
Definition: TVirtualPad.h:285
Definition: Rtypes.h:59