ROOT  6.06/09
Reference Guide
TBuffer3D.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id: TBuffer3D.cxx,v 1.00
2 // Author: Olivier Couet 05/05/04
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TBuffer3D.h"
13 #include "TBuffer3DTypes.h"
14 
15 /** \class TBuffer3D
16 Generic 3D primitive description class.
17 See TBuffer3DTypes for producer classes.
18 
19 ### Filling TBuffer3D and Adding to Viewer
20 
21 The viewers behind the TVirtualViewer3D interface differ greatly in their
22 capabilities e.g.
23 
24  - Some know how to draw certain shapes natively (e.g. spheres/tubes in OpenGL)
25  - others always require a raw tessellation description of points/lines/segments.
26  - Some need the 3D object positions in the global frame, others can cope with
27  local frames + a translation matrix - which can give considerable performance
28  benefits.
29 
30 To cope with these situations the object buffer is filled out in negotiation
31 with the viewer. TBuffer3D classes are conceptually divided into enumerated
32 sections Core, BoundingBox, Raw etc (see TBuffer3D.h for more details).
33 
34 \image html base_tbuffer3d.png
35 
36 The `SectionsValid() / SetSectionsValid / ClearSectionsValid()` methods of
37 TBuffer3D are used to test/set/clear these section valid flags.
38 
39 The sections found in TBuffer3D (`Core/BoundingBox/Raw Sizes/Raw`) are sufficient
40 to describe any tessellated shape in a generic fashion. An additional
41 `ShapeSpecific` section in derived shape specific classes allows a more abstract
42 shape description ("a sphere of inner radius x, outer radius y"). This
43 enables a viewer which knows how to draw (tessellate) the shape itself to do so,
44 which can bring considerable performance and quality benefits, while providing a
45 generic fallback suitable for all viewers.
46 
47 The rules for client negotiation with the viewer are:
48 
49  - If suitable specialized TBuffer3D class exists, use it, otherwise use TBuffer3D.
50  - Complete the mandatory Core section.
51  - Complete the ShapeSpecific section if applicable.
52  - Complete the BoundingBox if you can.
53  - Pass this buffer to the viewer using one of the AddObject() methods - see below.
54 
55 If the viewer requires more sections to be completed (Raw/RawSizes) AddObject()
56 will return flags indicating which ones, otherwise it returns kNone. You must
57 fill the buffer and mark these sections valid, and pass the buffer again. A
58 typical code snippet would be:
59 
60 ~~~ {.cpp}
61 TBuffer3DSphere sphereBuffer;
62 // Fill out kCore...
63 // Fill out kBoundingBox...
64 // Fill out kShapeSpecific for TBuffer3DSphere
65 // Try first add to viewer
66 Int_t reqSections = viewer->AddObject(buffer);
67 if (reqSections != TBuffer3D::kNone) {
68  if (reqSections & TBuffer3D::kRawSizes) {
69  // Fill out kRawSizes...
70  }
71  if (reqSections & TBuffer3D::kRaw) {
72  // Fill out kRaw...
73  }
74  // Add second time to viewer - ignore return cannot do more
75  viewer->AddObject(buffer);
76  }
77 }
78 ~~~
79 
80 `ShapeSpecific`: If the viewer can directly display the buffer without
81 filling of the kRaw/kRawSizes section it will not need to request client side
82 tessellation.
83 
84 Currently we provide the following various shape specific classes, which the
85 OpenGL viewer can take advantage of (see TBuffer3D.h and TBuffer3DTypes.h)
86 
87  - TBuffer3DSphere - solid, hollow and cut spheres*
88  - TBuffer3DTubeSeg - angle tube segment
89  - TBuffer3DCutTube - angle tube segment with plane cut ends.
90 
91 
92 *OpenGL only supports solid spheres at present - cut/hollow ones will be
93 requested tessellated.
94 
95 Anyone is free to add new TBuffer3D classes, but it should be clear that the
96 viewers require updating to be able to take advantage of them. The number of
97 native shapes in OpenGL will be expanded over time.
98 
99 `BoundingBox:` You are not obliged to complete this, as any viewer
100 requiring one internally (OpenGL) will build one for you if you do not provide.
101 However to do this the viewer will force you to provide the raw tessellation, and the
102 resulting box will be axis aligned with the overall scene, which is non-ideal
103 for rotated shapes.
104 
105 As we need to support orientated (rotated) bounding boxes, TBuffer3D requires
106 the 6 vertices of the box. We also provide a convenience function, SetAABoundingBox(),
107 for simpler case of setting an axis aligned bounding box.
108 
109 ### Master/Local Reference Frames
110 
111 The `Core` section of TBuffer3D contains two members relating to reference
112 frames:
113 `fLocalFrame` & `fLocalMaster`. `fLocalFrame` indicates if any positions in the
114 buffer (bounding box and tessellation vertexes) are in local or master (world frame).
115 `fLocalMaster` is a standard 4x4 translation matrix (OpenGL column major ordering)
116 for placing the object into the 3D master frame.
117 
118 If `fLocalFrame` is kFALSE, `fLocalMaster` should contain an identity matrix. This
119 is set by default, and can be reset using `SetLocalMasterIdentity()` function.
120 
121 Logical & Physical Objects.
122 There are two cases of object addition:
123 
124  - Add this object as a single independent entity in the world reference frame.
125  - Add a physical placement (copy) of this logical object (described in local
126  reference frame).
127 
128 The second case is very typical in geometry packages, GEANT4, where we have
129 very large number repeated placements of relatively few logical (unique) shapes.
130 Some viewers (OpenGL only at present) are able to take advantage of this by
131 identifying unique logical shapes from the `fID` logical ID member of
132 TBuffer3D. If repeated addition of the same `fID` is found, the shape
133 is cached already - and the costly tessellation does not need to be sent again.
134 The viewer can also perform internal GL specific caching with considerable
135 performance gains in these cases.
136 
137 For this to work correctly the logical object in must be described in TBuffer3D
138 in the local reference frame, complete with the local/master translation. The
139 viewer indicates this through the interface method
140 
141 ~~~ {.cpp}
142 PreferLocalFrame()
143 ~~~
144 
145 If this returns kTRUE you can make repeated calls to AddObject(), with TBuffer3D
146 containing the same fID, and different `fLocalMaster` placements.
147 
148 For viewers supporting logical/physical objects, the TBuffer3D content refers
149 to the properties of logical object, with the `fLocalMaster` transform and the
150 `fColor` and `fTransparency` attributes, which can be varied for each physical
151 object.
152 
153 As a minimum requirement all clients must be capable of filling the raw tessellation
154 of the object buffer, in the master reference frame. Conversely viewers must
155 always be capable of displaying the object described by this buffer.
156 
157 ### Scene Rebuilds
158 
159 It should be understood that AddObject is not an explicit command to the viewer
160  - it may for various reasons decide to ignore it:
161 
162  - It already has the object internally cached .
163  - The object falls outside some 'interest' limits of the viewer camera.
164  - The object is too small to be worth drawing.
165 
166 In all these cases AddObject() returns kNone, as it does for successful addition,
167 simply indicating it does not require you to provide further information about
168 this object. You should not try to make any assumptions about what the viewer
169 did with it.
170 
171 This enables the viewer to be connected to a client which sends potentially
172 millions of objects, and only accept those that are of interest at a certain
173 time, caching the relatively small number of CPU/memory costly logical shapes,
174 and retaining/discarding the physical placements as required. The viewer may
175 decide to force the client to rebuild (republish) the scene (via
176 a TPad repaint at present), and thus collect these objects if the
177 internal viewer state changes. It does this presently by forcing a repaint
178 on the attached TPad object - hence the reason for putting all publishing to
179 the viewer in the attached pad objects Paint() method. We will likely remove
180 this requirement in the future, indicating the rebuild request via a normal
181 ROOT signal, which the client can detect.
182 
183 ### Physical IDs
184 
185 TVirtualViewer3D provides for two methods of object addition:virtual Int_t AddObject(const
186 TBuffer3D & buffer, Bool_t * addChildren = 0)
187 
188 ~~~ {.cpp}
189 virtual Int_t AddObject(UInt_t physicalID, const TBuffer3D & buffer, Bool_t * addChildren = 0)
190 ~~~
191 
192 If you use the first (simple) case a viewer using logical/physical pairs
193 SetSectionsValid(TBuffer3D::kBoundingBox); will generate IDs for each physical
194 object internally. In the second you can specify a unique identifier from the
195 client, which allows the viewer to be more efficient. It can now cache both logical
196 and physical objects, and only discard physical objects no longer of interest as
197 part of scene rebuilds.
198 
199 ### Child Objects
200 
201 In many geometries there is a rigid containment hierarchy, and so if the viewer
202 is not interested in a certain object due to limits/size then it will also
203 not be interest in any of the contained branch of descendents. Both AddObject()
204 methods have an addChildren parameter. The viewer will complete this (if passed)
205 indicating if children (contained within the one just sent) are worth adding.
206 
207 ### Recycling TBuffer3D
208 
209 Once add AddObject() has been called, the contents are copied to the viewer
210 internally. You are free to destroy this object, or recycle it for the next
211 object if suitable.
212 */
213 
215 
216 ////////////////////////////////////////////////////////////////////////////////
217 /// Destructor.
218 /// Construct from supplied shape type and raw sizes
219 
221  UInt_t reqPnts, UInt_t reqPntsCapacity,
222  UInt_t reqSegs, UInt_t reqSegsCapacity,
223  UInt_t reqPols, UInt_t reqPolsCapacity) :
224  fType(type)
225 {
226  Init();
227  SetRawSizes(reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity);
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Destructor.
232 
234 {
235  if (fPnts) delete [] fPnts;
236  if (fSegs) delete [] fSegs;
237  if (fPols) delete [] fPols;
238 }
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 /// Initialise buffer.
242 
244 {
245  fID = 0;
246  fColor = 0;
247  // Set fLocalMaster in section kCore to identity
248  fTransparency = 0;
252 
253  // Reset bounding box
254  for (UInt_t v=0; v<8; v++) {
255  for (UInt_t i=0; i<3; i++) {
256  fBBVertex[v][i] = 0.0;
257  }
258  }
259  // Set fLocalMaster in section kCore to identity
260 
261  // Set kRaw tessellation section of buffer with supplied sizes
262  fPnts = 0;
263  fSegs = 0;
264  fPols = 0;
265 
266  fNbPnts = 0;
267  fNbSegs = 0;
268  fNbPols = 0;
269  fPntsCapacity = 0;
270  fSegsCapacity = 0;
271  fPolsCapacity = 0;
272  // Set fLocalMaster in section kCore to identity
273 
274  // Wipe output section.
275  fPhysicalID = 0;
276 
277  // Set kRaw tessellation section of buffer with supplied sizes
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Clear any sections marked valid.
283 
285 {
286  fSections = 0U;
287  SetRawSizes(0, 0, 0, 0, 0, 0);
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Set kRaw tessellation section of buffer with supplied sizes.
292 /// Set fLocalMaster in section kCore to identity
293 
295 {
296  for (UInt_t i=0; i<16; i++) {
297  if (i%5) {
298  fLocalMaster[i] = 0.0;
299  }
300  else {
301  fLocalMaster[i] = 1.0;
302  }
303  }
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Set fBBVertex in kBoundingBox section to a axis aligned (local) BB
308 /// using supplied origin and box half lengths.
309 ///~~~ {.cpp}
310 /// 7-------6
311 /// /| /|
312 /// 3-------2 |
313 /// | 4-----|-5
314 /// |/ |/
315 /// 0-------1
316 ///~~~
317 
318 void TBuffer3D::SetAABoundingBox(const Double_t origin[3], const Double_t halfLengths[3])
319 {
320  // Vertex 0
321  fBBVertex[0][0] = origin[0] - halfLengths[0]; // x
322  fBBVertex[0][1] = origin[1] - halfLengths[1]; // y
323  fBBVertex[0][2] = origin[2] - halfLengths[2]; // z
324  // Vertex 1
325  fBBVertex[1][0] = origin[0] + halfLengths[0]; // x
326  fBBVertex[1][1] = origin[1] - halfLengths[1]; // y
327  fBBVertex[1][2] = origin[2] - halfLengths[2]; // z
328  // Vertex 2
329  fBBVertex[2][0] = origin[0] + halfLengths[0]; // x
330  fBBVertex[2][1] = origin[1] + halfLengths[1]; // y
331  fBBVertex[2][2] = origin[2] - halfLengths[2]; // z
332  // Vertex 3
333  fBBVertex[3][0] = origin[0] - halfLengths[0]; // x
334  fBBVertex[3][1] = origin[1] + halfLengths[1]; // y
335  fBBVertex[3][2] = origin[2] - halfLengths[2]; // z
336  // Vertex 4
337  fBBVertex[4][0] = origin[0] - halfLengths[0]; // x
338  fBBVertex[4][1] = origin[1] - halfLengths[1]; // y
339  fBBVertex[4][2] = origin[2] + halfLengths[2]; // z
340  // Vertex 5
341  fBBVertex[5][0] = origin[0] + halfLengths[0]; // x
342  fBBVertex[5][1] = origin[1] - halfLengths[1]; // y
343  fBBVertex[5][2] = origin[2] + halfLengths[2]; // z
344  // Vertex 6
345  fBBVertex[6][0] = origin[0] + halfLengths[0]; // x
346  fBBVertex[6][1] = origin[1] + halfLengths[1]; // y
347  fBBVertex[6][2] = origin[2] + halfLengths[2]; // z
348  // Vertex 7
349  fBBVertex[7][0] = origin[0] - halfLengths[0]; // x
350  fBBVertex[7][1] = origin[1] + halfLengths[1]; // y
351  fBBVertex[7][2] = origin[2] + halfLengths[2]; // z
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Set kRaw tessellation section of buffer with supplied sizes.
356 
357 Bool_t TBuffer3D::SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity,
358  UInt_t reqSegs, UInt_t reqSegsCapacity,
359  UInt_t reqPols, UInt_t reqPolsCapacity)
360 {
361  Bool_t allocateOK = kTRUE;
362 
363  fNbPnts = reqPnts;
364  fNbSegs = reqSegs;
365  fNbPols = reqPols;
366 
367  if (reqPntsCapacity > fPntsCapacity) {
368  delete [] fPnts;
369  fPnts = new Double_t[reqPntsCapacity];
370  if (fPnts) {
371  fPntsCapacity = reqPntsCapacity;
372  } else {
373  fPntsCapacity = fNbPnts = 0;
374  allocateOK = kFALSE;
375  }
376  }
377  if (reqSegsCapacity > fSegsCapacity) {
378  delete [] fSegs;
379  fSegs = new Int_t[reqSegsCapacity];
380  if (fSegs) {
381  fSegsCapacity = reqSegsCapacity;
382  } else {
383  fSegsCapacity = fNbSegs = 0;
384  allocateOK = kFALSE;
385  }
386  }
387  if (reqPolsCapacity > fPolsCapacity) {
388  delete [] fPols;
389  fPols = new Int_t[reqPolsCapacity];
390  if (fPols) {
391  fPolsCapacity = reqPolsCapacity;
392  } else {
393  fPolsCapacity = fNbPols = 0;
394  allocateOK = kFALSE;
395  }
396  }
397 
398  return allocateOK;
399 }
400 
401 ////////////////////////////////////////////////////////////////////////////////
402 /// Constructor.
403 
405  UInt_t reqSegs, UInt_t reqSegsCapacity,
406  UInt_t reqPols, UInt_t reqPolsCapacity) :
407  TBuffer3D(TBuffer3DTypes::kSphere, reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity),
408  fRadiusInner(0.0), fRadiusOuter(0.0),
409  fThetaMin(0.0), fThetaMax(180.0),
410  fPhiMin(0.0), fPhiMax(360.0)
411 {
412 }
413 
414 ////////////////////////////////////////////////////////////////////////////////
415 /// Test if buffer represents a solid uncut sphere.
416 
418 {
419  if (fRadiusInner != 0.0 ||
420  fThetaMin != 0.0 ||
421  fThetaMax != 180.0 ||
422  fPhiMin != 0.0 ||
423  fPhiMax != 360.0 ) {
424  return kFALSE;
425  } else {
426  return kTRUE;
427  }
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// Constructor.
432 
433 TBuffer3DTube::TBuffer3DTube(UInt_t reqPnts, UInt_t reqPntsCapacity,
434  UInt_t reqSegs, UInt_t reqSegsCapacity,
435  UInt_t reqPols, UInt_t reqPolsCapacity) :
436  TBuffer3D(TBuffer3DTypes::kTube, reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity),
437  fRadiusInner(0.0), fRadiusOuter(1.0), fHalfLength(1.0)
438 {
439 }
440 
441 ////////////////////////////////////////////////////////////////////////////////
442 /// Constructor.
443 
445  UInt_t reqPnts, UInt_t reqPntsCapacity,
446  UInt_t reqSegs, UInt_t reqSegsCapacity,
447  UInt_t reqPols, UInt_t reqPolsCapacity) :
448  TBuffer3D(type, reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity),
449  fRadiusInner(0.0), fRadiusOuter(1.0), fHalfLength(1.0)
450 {
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Constructor.
455 
457  UInt_t reqSegs, UInt_t reqSegsCapacity,
458  UInt_t reqPols, UInt_t reqPolsCapacity) :
459  TBuffer3DTube(TBuffer3DTypes::kTubeSeg, reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity),
460  fPhiMin(0.0), fPhiMax(360.0)
461 {
462 }
463 
464 ////////////////////////////////////////////////////////////////////////////////
465 /// Constructor.
466 
468  UInt_t reqPnts, UInt_t reqPntsCapacity,
469  UInt_t reqSegs, UInt_t reqSegsCapacity,
470  UInt_t reqPols, UInt_t reqPolsCapacity) :
471  TBuffer3DTube(type, reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity),
472  fPhiMin(0.0), fPhiMax(360.0)
473 {
474 }
475 
476 ////////////////////////////////////////////////////////////////////////////////
477 /// Constructor.
478 
480  UInt_t reqSegs, UInt_t reqSegsCapacity,
481  UInt_t reqPols, UInt_t reqPolsCapacity) :
482  TBuffer3DTubeSeg(TBuffer3DTypes::kCutTube, reqPnts, reqPntsCapacity, reqSegs, reqSegsCapacity, reqPols, reqPolsCapacity)
483 {
484  fLowPlaneNorm[0] = 0.0; fLowPlaneNorm[0] = 0.0; fLowPlaneNorm[0] = -1.0;
485  fHighPlaneNorm[0] = 0.0; fHighPlaneNorm[0] = 0.0; fHighPlaneNorm[0] = 1.0;
486 }
487 
488 //CS specific
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Return CS level.
493 
495 {
496  return fgCSLevel;
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 /// Increment CS level.
501 
503 {
504  ++fgCSLevel;
505 }
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 /// Decrement CS level.
509 
511 {
512  return --fgCSLevel;
513 }
Double_t fThetaMax
Definition: TBuffer3D.h:148
Complete tube description class - see TBuffer3DTypes for producer classes.
Definition: TBuffer3D.h:157
Double_t fHighPlaneNorm[3]
Definition: TBuffer3D.h:226
Double_t fThetaMin
Definition: TBuffer3D.h:147
Bool_t IsSolidUncut() const
Test if buffer represents a solid uncut sphere.
Definition: TBuffer3D.cxx:417
Double_t fBBVertex[8][3]
Definition: TBuffer3D.h:109
Tube segment description class - see TBuffer3DTypes for producer classes.
Definition: TBuffer3D.h:185
UInt_t fSections
Definition: TBuffer3D.h:32
Double_t fLocalMaster[16]
Definition: TBuffer3D.h:94
void SetLocalMasterIdentity()
Set kRaw tessellation section of buffer with supplied sizes.
Definition: TBuffer3D.cxx:294
TBuffer3DTube(const TBuffer3DTube &)
void ClearSectionsValid()
Clear any sections marked valid.
Definition: TBuffer3D.cxx:284
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
UInt_t fNbSegs
Definition: TBuffer3D.h:25
static UInt_t GetCSLevel()
Return CS level.
Definition: TBuffer3D.cxx:494
Double_t fRadiusInner
Definition: TBuffer3D.h:145
UInt_t fNbPols
Definition: TBuffer3D.h:26
TBuffer3DSphere(const TBuffer3DSphere &)
UInt_t fNbPnts
Definition: TBuffer3D.h:24
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:118
Double_t * fPnts
Definition: TBuffer3D.h:114
static void IncCSLevel()
Increment CS level.
Definition: TBuffer3D.cxx:502
Int_t * fPols
Definition: TBuffer3D.h:116
Bool_t fLocalFrame
Definition: TBuffer3D.h:92
Double_t fPhiMax
Definition: TBuffer3D.h:150
TBuffer3DTubeSeg(const TBuffer3DTubeSeg &)
static UInt_t fgCSLevel
Definition: TBuffer3D.h:41
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:318
SVector< double, 2 > v
Definition: Dict.h:5
UInt_t fPhysicalID
Definition: TBuffer3D.h:120
unsigned int UInt_t
Definition: RtypesCore.h:42
UInt_t fPolsCapacity
Definition: TBuffer3D.h:30
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:357
Generic 3D primitive description class.
Definition: TBuffer3D.h:19
TObject * fID
Definition: TBuffer3D.h:89
Double_t fPhiMin
Definition: TBuffer3D.h:149
TBuffer3DCutTube(const TBuffer3DTubeSeg &)
static UInt_t DecCSLevel()
Decrement CS level.
Definition: TBuffer3D.cxx:510
UInt_t fPntsCapacity
Definition: TBuffer3D.h:28
PyObject * fType
Bool_t fReflection
Definition: TBuffer3D.h:93
double Double_t
Definition: RtypesCore.h:55
Double_t fLowPlaneNorm[3]
Definition: TBuffer3D.h:225
int type
Definition: TGX11.cxx:120
Int_t fColor
Definition: TBuffer3D.h:90
void Init()
Initialise buffer.
Definition: TBuffer3D.cxx:243
Int_t * fSegs
Definition: TBuffer3D.h:115
UInt_t fSegsCapacity
Definition: TBuffer3D.h:29
virtual ~TBuffer3D()
Destructor.
Definition: TBuffer3D.cxx:233
Short_t fTransparency
Definition: TBuffer3D.h:91
const Bool_t kTRUE
Definition: Rtypes.h:91
ClassImp(TBuffer3D) TBuffer3D
Destructor.
Definition: TBuffer3D.cxx:214