viewer3DLocal.C

Go to the documentation of this file.
00001 //+ Demonstrates 3D viewer architecture TVirtualViewer3D and TBuffer3D in the local frame.
00002 //
00003 // Here each shape is described in a TBuffer3D class, 
00004 // with a suitible translation matrix to place each instance
00005 // NOTE: to be executed via .x viewer3DLocal.C+
00006 //
00007 // NOTE: We don't implement raw tesselation of sphere - hence this will 
00008 // not appear in viewers which don't support directly (non-OpenGL)
00009 // Shows that viewers can at least deal gracefully with these cases
00010 
00011 // Our abstract base shape class.
00012 // Author: Richard Maunder
00013 
00014 // As we overload TObject::Paint which is called directly from compiled
00015 // code, this script must also be compiled to work correctly.
00016 
00017 //#if defined(__CINT__) && !defined(__MAKECINT__)
00018 //{
00019 //   gSystem->CompileMacro("viewer3DLocal.C");
00020 //   viewer3DLocal();
00021 //}
00022 //#else
00023 
00024 #include "TVirtualViewer3D.h"
00025 #include "TBuffer3D.h"
00026 #include "TBuffer3DTypes.h"
00027 
00028 #include "TObject.h"
00029 #include "TVirtualPad.h"
00030 #include "TAtt3D.h"
00031 
00032 #include <vector>
00033 
00034 class Shape : public TObject
00035 {
00036 public:
00037    Shape(Int_t color, Double_t x, Double_t y, Double_t z);
00038    ~Shape() {};
00039    virtual TBuffer3D & GetBuffer3D(UInt_t reqSections) = 0;
00040 
00041 protected:
00042    Double_t fX, fY, fZ;    // Origin
00043    Int_t fColor;
00044 
00045    ClassDef(Shape,0);
00046 };
00047 
00048 ClassImp(Shape); 
00049 
00050 Shape::Shape(Int_t color, Double_t x, Double_t y, Double_t z) : 
00051    fX(x), fY(y), fZ(z), fColor(color) 
00052 {}
00053 
00054 class Sphere : public Shape
00055 {
00056 public:
00057    Sphere(Int_t color, Double_t x, Double_t y, Double_t z, Double_t radius);
00058    ~Sphere() {};
00059 
00060    virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);
00061 
00062 private:
00063    Double_t fRadius;
00064 
00065    ClassDef(Sphere,0);
00066 };
00067 
00068 ClassImp(Sphere); 
00069 
00070 Sphere::Sphere(Int_t color, Double_t x, Double_t y, Double_t z, Double_t radius) : 
00071    Shape(color,x,y,z), 
00072    fRadius(radius) 
00073 {}
00074 
00075 TBuffer3D & Sphere::GetBuffer3D(UInt_t reqSections)
00076 {
00077    static TBuffer3DSphere buffer;
00078 
00079    // Complete kCore section - this could be moved to Shape base class
00080    if (reqSections & TBuffer3D::kCore) { 
00081       buffer.ClearSectionsValid();
00082       buffer.fID = this; 
00083       buffer.fColor = fColor;       // Color index - see gROOT->GetColor()
00084       buffer.fTransparency = 0;     // Transparency 0 (opaque) - 100 (fully transparent)
00085 
00086       // Complete local/master transformation matrix - simple x/y/z 
00087       // translation. Easiest way to set identity then override the 
00088       // translation components
00089       buffer.SetLocalMasterIdentity();
00090       buffer.fLocalMaster[12] = fX;
00091       buffer.fLocalMaster[13] = fY;
00092       buffer.fLocalMaster[14] = fZ;
00093       buffer.fLocalFrame = kTRUE;  // Local frame
00094 
00095       buffer.fReflection = kFALSE;
00096       buffer.SetSectionsValid(TBuffer3D::kCore);
00097    }
00098    // Complete kBoundingBox section
00099    if (reqSections & TBuffer3D::kBoundingBox) {
00100       Double_t origin[3] = { 0.0, 0.0, 0.0 };
00101       Double_t halfLength[3] = { fRadius, fRadius, fRadius };
00102       buffer.SetAABoundingBox(origin, halfLength);
00103       buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
00104    }
00105    // Complete kShapeSpecific section
00106    if (reqSections & TBuffer3D::kShapeSpecific) {
00107       buffer.fRadiusOuter = fRadius;
00108       buffer.fRadiusInner = 0.0;
00109       buffer.fThetaMin    = 0.0;
00110       buffer.fThetaMax    = 180.0;
00111       buffer.fPhiMin    = 0.0;
00112       buffer.fPhiMax    = 360.0;
00113       buffer.SetSectionsValid(TBuffer3D::kShapeSpecific);
00114    }
00115    // We don't implement raw tesselation of sphere - hence this will 
00116    // not appear in viewers which don't support directly (non-OpenGL)
00117    // Complete kRawSizes section
00118    if (reqSections & TBuffer3D::kRawSizes) {
00119       //buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00120    }
00121    // Complete kRaw section
00122    if (reqSections & TBuffer3D::kRaw) {
00123       //buffer.SetSectionsValid(TBuffer3D::kRaw);
00124    }
00125 
00126    return buffer;
00127 }
00128 
00129 class Box : public Shape
00130 {
00131 public:
00132    Box(Int_t color, Double_t x, Double_t y, Double_t z,
00133        Double_t dX, Double_t dY, Double_t dZ);
00134    ~Box() {};
00135 
00136    virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);
00137 
00138 private:
00139    Double_t fDX, fDY, fDZ; // Half lengths
00140 
00141    ClassDef(Box,0);
00142 };
00143 
00144 ClassImp(Box); 
00145 
00146 Box::Box(Int_t color, Double_t x, Double_t y, Double_t z,
00147          Double_t dX, Double_t dY, Double_t dZ) : 
00148    Shape(color,x,y,z), 
00149    fDX(dX), fDY(dY), fDZ(dZ)
00150 {}
00151 
00152 TBuffer3D & Box::GetBuffer3D(UInt_t reqSections)
00153 {
00154    static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00155 
00156    // Complete kCore section - this could be moved to Shape base class
00157    if (reqSections & TBuffer3D::kCore) {      
00158       buffer.ClearSectionsValid();
00159       buffer.fID = this; 
00160       buffer.fColor = fColor;       // Color index - see gROOT->GetColor()
00161       buffer.fTransparency = 0;     // Transparency 0 (opaque) - 100 (fully transparent)
00162 
00163       // Complete local/master transformation matrix - simple x/y/z 
00164       // translation. Easiest way to set identity then override the 
00165       // translation components
00166       buffer.SetLocalMasterIdentity();
00167       buffer.fLocalMaster[12] = fX;
00168       buffer.fLocalMaster[13] = fY;
00169       buffer.fLocalMaster[14] = fZ;
00170       buffer.fLocalFrame = kTRUE;  // Local frame
00171 
00172       buffer.fReflection = kFALSE;
00173       buffer.SetSectionsValid(TBuffer3D::kCore);
00174    }
00175    // Complete kBoundingBox section
00176    if (reqSections & TBuffer3D::kBoundingBox) {
00177       Double_t origin[3] = { fX, fY, fZ };
00178       Double_t halfLength[3] =  { fDX, fDY, fDZ };
00179       buffer.SetAABoundingBox(origin, halfLength);
00180       buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
00181    }
00182    // No kShapeSpecific section
00183 
00184    // Complete kRawSizes section
00185    if (reqSections & TBuffer3D::kRawSizes) {
00186       buffer.SetRawSizes(8, 3*8, 12, 3*12, 6, 6*6);
00187       buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00188    }
00189    // Complete kRaw section
00190    if (reqSections & TBuffer3D::kRaw) {
00191       // Points (8)
00192       // 3 components: x,y,z
00193       buffer.fPnts[ 0] = fX - fDX; buffer.fPnts[ 1] = fY - fDY; buffer.fPnts[ 2] = fZ - fDZ; // 0
00194       buffer.fPnts[ 3] = fX + fDX; buffer.fPnts[ 4] = fY - fDY; buffer.fPnts[ 5] = fZ - fDZ; // 1
00195       buffer.fPnts[ 6] = fX + fDX; buffer.fPnts[ 7] = fY + fDY; buffer.fPnts[ 8] = fZ - fDZ; // 2
00196       buffer.fPnts[ 9] = fX - fDX; buffer.fPnts[10] = fY + fDY; buffer.fPnts[11] = fZ - fDZ; // 3
00197       buffer.fPnts[12] = fX - fDX; buffer.fPnts[13] = fY - fDY; buffer.fPnts[14] = fZ + fDZ; // 4
00198       buffer.fPnts[15] = fX + fDX; buffer.fPnts[16] = fY - fDY; buffer.fPnts[17] = fZ + fDZ; // 5
00199       buffer.fPnts[18] = fX + fDX; buffer.fPnts[19] = fY + fDY; buffer.fPnts[20] = fZ + fDZ; // 6
00200       buffer.fPnts[21] = fX - fDX; buffer.fPnts[22] = fY + fDY; buffer.fPnts[23] = fZ + fDZ; // 7
00201 
00202       // Segments (12)
00203       // 3 components: segment color(ignored), start point index, end point index
00204       // Indexes reference the above points
00205       buffer.fSegs[ 0] = fColor   ; buffer.fSegs[ 1] = 0   ; buffer.fSegs[ 2] = 1   ; // 0
00206       buffer.fSegs[ 3] = fColor   ; buffer.fSegs[ 4] = 1   ; buffer.fSegs[ 5] = 2   ; // 1
00207       buffer.fSegs[ 6] = fColor   ; buffer.fSegs[ 7] = 2   ; buffer.fSegs[ 8] = 3   ; // 2
00208       buffer.fSegs[ 9] = fColor   ; buffer.fSegs[10] = 3   ; buffer.fSegs[11] = 0   ; // 3
00209       buffer.fSegs[12] = fColor   ; buffer.fSegs[13] = 4   ; buffer.fSegs[14] = 5   ; // 4
00210       buffer.fSegs[15] = fColor   ; buffer.fSegs[16] = 5   ; buffer.fSegs[17] = 6   ; // 5
00211       buffer.fSegs[18] = fColor   ; buffer.fSegs[19] = 6   ; buffer.fSegs[20] = 7   ; // 6
00212       buffer.fSegs[21] = fColor   ; buffer.fSegs[22] = 7   ; buffer.fSegs[23] = 4   ; // 7
00213       buffer.fSegs[24] = fColor   ; buffer.fSegs[25] = 0   ; buffer.fSegs[26] = 4   ; // 8
00214       buffer.fSegs[27] = fColor   ; buffer.fSegs[28] = 1   ; buffer.fSegs[29] = 5   ; // 9
00215       buffer.fSegs[30] = fColor   ; buffer.fSegs[31] = 2   ; buffer.fSegs[32] = 6   ; // 10
00216       buffer.fSegs[33] = fColor   ; buffer.fSegs[34] = 3   ; buffer.fSegs[35] = 7   ; // 11
00217       
00218       // Polygons (6)
00219       // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
00220       // seg1, seg2 .... segn index
00221       // Segments indexes refer to the above 12 segments
00222       // Here n=4 - each polygon defines a rectangle - 4 sides.
00223       buffer.fPols[ 0] = fColor   ; buffer.fPols[ 1] = 4   ;  buffer.fPols[ 2] = 8  ; // 0
00224       buffer.fPols[ 3] = 4        ; buffer.fPols[ 4] = 9   ;  buffer.fPols[ 5] = 0  ;
00225       buffer.fPols[ 6] = fColor   ; buffer.fPols[ 7] = 4   ;  buffer.fPols[ 8] = 9  ; // 1
00226       buffer.fPols[ 9] = 5        ; buffer.fPols[10] = 10  ;  buffer.fPols[11] = 1  ;
00227       buffer.fPols[12] = fColor   ; buffer.fPols[13] = 4   ;  buffer.fPols[14] = 10  ; // 2
00228       buffer.fPols[15] = 6        ; buffer.fPols[16] = 11  ;  buffer.fPols[17] = 2  ;
00229       buffer.fPols[18] = fColor   ; buffer.fPols[19] = 4   ;  buffer.fPols[20] = 11 ; // 3
00230       buffer.fPols[21] = 7        ; buffer.fPols[22] = 8   ;  buffer.fPols[23] = 3 ;
00231       buffer.fPols[24] = fColor   ; buffer.fPols[25] = 4   ;  buffer.fPols[26] = 1  ; // 4
00232       buffer.fPols[27] = 2        ; buffer.fPols[28] = 3   ;  buffer.fPols[29] = 0  ;
00233       buffer.fPols[30] = fColor   ; buffer.fPols[31] = 4   ;  buffer.fPols[32] = 7  ; // 5
00234       buffer.fPols[33] = 6        ; buffer.fPols[34] = 5   ;  buffer.fPols[35] = 4  ;
00235       
00236       buffer.SetSectionsValid(TBuffer3D::kRaw);
00237   }
00238 
00239    return buffer;
00240 }
00241 
00242 class SBPyramid : public Shape
00243 {
00244 public:
00245    SBPyramid(Int_t color, Double_t d, Double_t y, Double_t z,
00246              Double_t dX, Double_t dY, Double_t dZ);
00247    ~SBPyramid() {};
00248 
00249    virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);
00250 
00251 private:
00252    Double_t fDX, fDY, fDZ; // Base half lengths dX,dY
00253                            // Pyr. height dZ
00254 
00255    ClassDef(SBPyramid,0);
00256 };
00257 
00258 ClassImp(SBPyramid); 
00259 
00260 SBPyramid::SBPyramid(Int_t color, Double_t x, Double_t y, Double_t z,
00261          Double_t dX, Double_t dY, Double_t dZ) : 
00262    Shape(color,x,y,z), 
00263    fDX(dX), fDY(dY), fDZ(dZ)
00264 {}
00265 
00266 TBuffer3D & SBPyramid::GetBuffer3D(UInt_t reqSections)
00267 {
00268    static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00269 
00270    // Complete kCore section
00271    if (reqSections & TBuffer3D::kCore) {      
00272       buffer.ClearSectionsValid();
00273       buffer.fID = this; 
00274       buffer.fColor = fColor;       // Color index - see gROOT->GetColor()
00275       buffer.fTransparency = 0;     // Transparency 0 (opaque) - 100 (fully transparent)
00276 
00277       // Complete local/master transformation matrix - simple x/y/z 
00278       // translation. Easiest way to set identity then override the 
00279       // translation components
00280       buffer.SetLocalMasterIdentity();
00281       buffer.fLocalMaster[12] = fX;
00282       buffer.fLocalMaster[13] = fY;
00283       buffer.fLocalMaster[14] = fZ;
00284       buffer.fLocalFrame = kTRUE;  // Local frame
00285 
00286       buffer.fReflection = kFALSE;
00287       buffer.SetSectionsValid(TBuffer3D::kCore);
00288    }
00289    // Complete kBoundingBox section
00290    if (reqSections & TBuffer3D::kBoundingBox) {
00291       Double_t halfLength[3] =  { fDX, fDY, fDZ/2.0 };
00292       Double_t origin[3] = { fX , fY, fZ + halfLength[2]};
00293       buffer.SetAABoundingBox(origin, halfLength);
00294       buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
00295    }
00296    // No kShapeSpecific section
00297 
00298    // Complete kRawSizes section
00299    if (reqSections & TBuffer3D::kRawSizes) {
00300       buffer.SetRawSizes(5, 3*5, 8, 3*8, 5, 6 + 4*5);
00301       buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00302    }
00303    // Complete kRaw section
00304    if (reqSections & TBuffer3D::kRaw) {
00305       // Points (5)
00306       // 3 components: x,y,z
00307       buffer.fPnts[ 0] = fX - fDX; buffer.fPnts[ 1] = fY - fDY; buffer.fPnts[ 2] = fZ; // 0
00308       buffer.fPnts[ 3] = fX + fDX; buffer.fPnts[ 4] = fY - fDY; buffer.fPnts[ 5] = fZ; // 1
00309       buffer.fPnts[ 6] = fX + fDX; buffer.fPnts[ 7] = fY + fDY; buffer.fPnts[ 8] = fZ; // 2
00310       buffer.fPnts[ 9] = fX - fDX; buffer.fPnts[10] = fY + fDY; buffer.fPnts[11] = fZ; // 3
00311       buffer.fPnts[12] = fX;       buffer.fPnts[13] = fY      ; buffer.fPnts[14] = fZ + fDZ; // 4 (pyr top point)
00312 
00313       // Segments (8)
00314       // 3 components: segment color(ignored), start point index, end point index
00315       // Indexes reference the above points
00316 
00317       buffer.fSegs[ 0] = fColor   ; buffer.fSegs[ 1] = 0   ; buffer.fSegs[ 2] = 1   ; // 0 base
00318       buffer.fSegs[ 3] = fColor   ; buffer.fSegs[ 4] = 1   ; buffer.fSegs[ 5] = 2   ; // 1 base
00319       buffer.fSegs[ 6] = fColor   ; buffer.fSegs[ 7] = 2   ; buffer.fSegs[ 8] = 3   ; // 2 base
00320       buffer.fSegs[ 9] = fColor   ; buffer.fSegs[10] = 3   ; buffer.fSegs[11] = 0   ; // 3 base
00321       buffer.fSegs[12] = fColor   ; buffer.fSegs[13] = 0   ; buffer.fSegs[14] = 4   ; // 4 side
00322       buffer.fSegs[15] = fColor   ; buffer.fSegs[16] = 1   ; buffer.fSegs[17] = 4   ; // 5 side
00323       buffer.fSegs[18] = fColor   ; buffer.fSegs[19] = 2   ; buffer.fSegs[20] = 4   ; // 6 side
00324       buffer.fSegs[21] = fColor   ; buffer.fSegs[22] = 3   ; buffer.fSegs[23] = 4   ; // 7 side
00325       
00326       // Polygons (6)
00327       // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
00328       // seg1, seg2 .... segn index
00329       // Segments indexes refer to the above 12 segments
00330       // Here n=4 - each polygon defines a rectangle - 4 sides.
00331       buffer.fPols[ 0] = fColor  ; buffer.fPols[ 1] = 4   ;  buffer.fPols[ 2] = 0  ; // base
00332       buffer.fPols[ 3] = 1       ; buffer.fPols[ 4] = 2   ;  buffer.fPols[ 5] = 3  ;
00333 
00334       buffer.fPols[ 6] = fColor  ; buffer.fPols[ 7] = 3   ;  buffer.fPols[ 8] = 0  ; // side 0
00335       buffer.fPols[ 9] = 4       ; buffer.fPols[10] = 5   ;
00336       buffer.fPols[11] = fColor  ; buffer.fPols[12] = 3   ;  buffer.fPols[13] = 1  ; // side 1
00337       buffer.fPols[14] = 5       ; buffer.fPols[15] = 6   ;
00338       buffer.fPols[16] = fColor  ; buffer.fPols[17] = 3   ;  buffer.fPols[18] = 2  ; // side 2
00339       buffer.fPols[19] = 6       ; buffer.fPols[20] = 7   ;   
00340       buffer.fPols[21] = fColor  ; buffer.fPols[22] = 3   ;  buffer.fPols[23] = 3  ; // side 3
00341       buffer.fPols[24] = 7       ; buffer.fPols[25] = 4   ;
00342       
00343       buffer.SetSectionsValid(TBuffer3D::kRaw);
00344   }
00345 
00346    return buffer;
00347 }
00348 
00349 class MyGeom : public TObject, public TAtt3D
00350 {
00351 public:
00352    MyGeom();
00353    ~MyGeom();
00354 
00355    void Draw(Option_t *option);
00356    void Paint(Option_t *option);
00357 
00358 private:
00359    std::vector<Shape *> fShapes;
00360 
00361    ClassDef(MyGeom,0);
00362 };
00363 
00364 ClassImp(MyGeom); 
00365 
00366 MyGeom::MyGeom()
00367 {
00368    // Create our simple geometry - sphere, couple of boxes
00369    // and a square base pyramid
00370    Shape * aShape;
00371    aShape = new Sphere(kYellow, 80.0, 60.0, 120.0, 10.0);
00372    fShapes.push_back(aShape);
00373    aShape = new Box(kRed, 0.0, 0.0, 0.0, 20.0, 20.0, 20.0);
00374    fShapes.push_back(aShape);
00375    aShape = new Box(kBlue, 50.0, 100.0, 200.0, 5.0, 10.0, 15.0);
00376    fShapes.push_back(aShape);
00377    aShape = new SBPyramid(kGreen, 20.0, 25.0, 45.0, 30.0, 30.0, 90.0);
00378    fShapes.push_back(aShape);
00379 }
00380 
00381 MyGeom::~MyGeom()
00382 {
00383    // Clear out fShapes
00384 }
00385 
00386 void MyGeom::Draw(Option_t *option)
00387 {
00388    TObject::Draw(option);
00389 
00390    // Ask pad to create 3D viewer of type 'option'
00391    gPad->GetViewer3D(option);
00392 }
00393 
00394 void MyGeom::Paint(Option_t * /*option*/)
00395 {
00396    TVirtualViewer3D * viewer = gPad->GetViewer3D();
00397 
00398    // If MyGeom derives from TAtt3D then pad will recognise
00399    // that the object it is asking to paint is 3D, and open/close
00400    // the scene for us. If not Open/Close are required
00401    //viewer->BeginScene();
00402 
00403    // We are working in the master frame - so we don't bother
00404    // to ask the viewer if it prefers local. Viewer's must
00405    // always support master frame as minimum. c.f. with
00406    // viewer3DLocal.C
00407    std::vector<Shape *>::const_iterator ShapeIt = fShapes.begin();
00408    Shape * shape;
00409    while (ShapeIt != fShapes.end()) {
00410       shape = *ShapeIt;
00411 
00412       UInt_t reqSections = TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific;
00413       TBuffer3D & buffer = shape->GetBuffer3D(reqSections);
00414       reqSections = viewer->AddObject(buffer);
00415 
00416       if (reqSections != TBuffer3D::kNone) {
00417          shape->GetBuffer3D(reqSections);
00418          viewer->AddObject(buffer);
00419       }
00420       ShapeIt++;
00421    }
00422    // Not required as we are TAtt3D subclass
00423    //viewer->EndScene();
00424 }
00425 
00426 void viewer3DLocal()
00427 {
00428    printf("\n\nviewer3DLocal: This frame demonstates local frame use of 3D viewer architecture.\n");
00429    printf("Creates sphere, two boxes and a square based pyramid, described in local frame.\n");
00430    printf("We do not implement raw tesselation of sphere - hence will not appear in viewers\n");
00431    printf("which do not support in natively (non-GL viewer).\n\n");
00432 
00433    MyGeom * myGeom = new MyGeom;
00434    myGeom->Draw("ogl");
00435 }
00436 
00437 //#endif

Generated on Tue Jul 5 15:44:20 2011 for ROOT_528-00b_version by  doxygen 1.5.1