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