TXTRU.cxx

Go to the documentation of this file.
00001 // @@(#)root/g3d:$Id: TXTRU.cxx 35110 2010-09-01 15:45:48Z matevz $
00002 // Author: Robert Hatcher (rhatcher@fnal.gov) 2000.09.06
00003 
00004 #include "TXTRU.h"
00005 #include "TVirtualPad.h"
00006 
00007 ///#include "GLConstants.h"
00008 
00009 #include "TBuffer3D.h"
00010 #include "TBuffer3DTypes.h"
00011 #include "TGeometry.h"
00012 #include "TMath.h"
00013 
00014 #include "Riostream.h"
00015 
00016 
00017 ClassImp(TXTRU)
00018 
00019 
00020 //_____________________________________________________________________________
00021 // Begin_Html <P ALIGN=CENTER> <IMG SRC="gif/xtru.gif"> </P> End_Html
00022 //
00023 // XTRU is an poly-extrusion with fixed outline shape in x-y,
00024 // a sequence of z extents (segments) and two end faces perpendicular
00025 // to the z axis.  The x-y outline is defined by an ordered list of
00026 // points; the overall scale of the outline scales linearly between
00027 // z points and the center can have an x-y offset specified
00028 // at each segment end.
00029 //
00030 // A TXTRU has the following parameters:
00031 //
00032 //     - name       name of the shape
00033 //     - title      shape's title
00034 //     - material  (see TMaterial)
00035 //     - nxy        number of x-y vertex points constituting the outline --
00036 //                  this number should be at least 3
00037 //     - nz         number of planes perpendicular to the z axis where
00038 //                  the scaling dimension of the section is given --
00039 //                  this number should be at least 2
00040 //     - Xvtx       array [nxy] of X coordinates of vertices
00041 //     - Yvtx       array [nxy] of Y coordinates of vertices
00042 //     - z          array [nz] of z plane positions
00043 //     - scale      array [nz] of scale factors
00044 //     - x0         array [nz] of x offsets
00045 //     - y0         array [nz] of y offsets
00046 //
00047 // Author:  R. Hatcher 2000.04.21
00048 //
00049 // All XTRU shapes are correctly rendered in wire mode but can encounter
00050 // difficulty when rendered as a solid with hidden surfaces.  These
00051 // exceptions occur if the outline shape is not a convex polygon.
00052 // Both the X3D and OpenGL renderers expect polygons to be convex.
00053 // The OpenGL spec specifies that points defining a polygon using the
00054 // GL_POLYGON primitive may be rendered as the convex hull of that set.
00055 //
00056 // Solid rendering under X3D can also give unexpected artifacts if
00057 // the combination of x-y-z offsets and scales for the segments are
00058 // chosen in such a manner that they represent a concave shape when
00059 // sliced along a plane parallel to the z axis.
00060 //
00061 // Choosing sets of point that represent a malformed polygon is
00062 // not supported, but testing for such a condition is not implemented
00063 // and thus it is left to the user to avoid this mistake.
00064 //
00065 // Begin_Html <P ALIGN=CENTER> <IMG SRC="gif/polytype.gif"> </P> End_Html
00066 
00067 
00068 //______________________________________________________________________________
00069 TXTRU::TXTRU()
00070    : fNxy(0), fNxyAlloc(0), fNz(0), fNzAlloc(0), fXvtx(0), fYvtx(0),
00071      fZ(0), fScale(0), fX0(0), fY0(0)
00072 {
00073    // TXTRU shape - default constructor
00074 
00075    fPolygonShape  = kUncheckedXY;
00076    fZOrdering     = kUncheckedZ;
00077    fSplitConcave  = kFALSE;
00078 }
00079 
00080 
00081 //______________________________________________________________________________
00082 TXTRU::TXTRU(const char *name, const char *title, const char *material,
00083              Int_t nxy, Int_t nz)
00084    : TShape (name,title,material)
00085 {
00086    // TXTRU shape - normal constructor
00087    //
00088    // Parameters of Nxy positions must be entered via TXTRU::DefineVertex
00089    // Parameters of Nz  positions must be entered via TXTRU::DefineSection
00090 
00091    // start in a known state even if "Error" is encountered
00092    fNxy      = 0;
00093    fNxyAlloc = 0;
00094    fNz       = 0;
00095    fNzAlloc  = 0;
00096    fXvtx     = 0;
00097    fYvtx     = 0;
00098    fZ        = 0;
00099    fScale    = 0;
00100    fX0       = 0;
00101    fY0       = 0;
00102 
00103    fPolygonShape  = kUncheckedXY;
00104    fZOrdering     = kUncheckedZ;
00105    fSplitConcave  = kFALSE;
00106 
00107    if ( nxy < 3 ) {
00108       Error(name,"number of x-y points for %s must be at least three!",name);
00109       return;
00110    }
00111    if ( nz < 2 ) {
00112       Error(name,"number of z points for %s must be at least two!",name);
00113       return;
00114    }
00115 
00116    // allocate space for Nxy vertex points
00117    fNxy       = nxy;
00118    fNxyAlloc  = nxy;
00119    fXvtx      = new Float_t [fNxyAlloc];
00120    fYvtx      = new Float_t [fNxyAlloc];
00121    // zero out the vertex points
00122    Int_t i = 0;
00123    for (i = 0; i < fNxyAlloc; i++) {
00124       fXvtx[i] = 0;
00125       fYvtx[i] = 0;
00126    }
00127 
00128    // allocate space for Nz sections
00129    fNz        = nz;
00130    fNzAlloc   = nz;
00131    fZ         = new Float_t [fNzAlloc];
00132    fScale     = new Float_t [fNzAlloc];
00133    fX0        = new Float_t [fNzAlloc];
00134    fY0        = new Float_t [fNzAlloc];
00135    // zero out the z points
00136    Int_t j = 0;
00137    for (j = 0; j < fNzAlloc; j++) {
00138       fZ[j]     = 0;
00139       fScale[j] = 0;
00140       fX0[j]    = 0;
00141       fY0[j]    = 0;
00142    }
00143 
00144 }
00145 
00146 
00147 //______________________________________________________________________________
00148 TXTRU::TXTRU(const TXTRU &xtru) : TShape(xtru)
00149 {
00150    // TXTRU copy constructor
00151 
00152    // patterned after other ROOT objects
00153 
00154    ((TXTRU&)xtru).Copy(*this);
00155 }
00156 
00157 
00158 //______________________________________________________________________________
00159 TXTRU::~TXTRU()
00160 {
00161    // TXTRU destructor deallocates arrays
00162 
00163    if (fXvtx) delete [] fXvtx;
00164    if (fYvtx) delete [] fYvtx;
00165    fXvtx     = 0;
00166    fYvtx     = 0;
00167    fNxy      = 0;
00168    fNxyAlloc = 0;
00169 
00170    if (fZ)     delete [] fZ;
00171    if (fScale) delete [] fScale;
00172    if (fX0)    delete [] fX0;
00173    if (fY0)    delete [] fY0;
00174    fZ        = 0;
00175    fScale    = 0;
00176    fX0       = 0;
00177    fY0       = 0;
00178    fNz       = 0;
00179    fNzAlloc  = 0;
00180 
00181    fPolygonShape  = kUncheckedXY;
00182    fZOrdering     = kUncheckedZ;
00183 }
00184 
00185 
00186 //______________________________________________________________________________
00187 TXTRU& TXTRU::operator=(const TXTRU &rhs)
00188 {
00189    // Deep assignment operator
00190 
00191    // protect against self-assignment
00192    if (this == &rhs) return *this;
00193 
00194    if (fNxyAlloc) {
00195       delete [] fXvtx;
00196       delete [] fYvtx;
00197    }
00198    if (fNzAlloc) {
00199       delete [] fZ;
00200       delete [] fScale;
00201       delete [] fX0;
00202       delete [] fY0;
00203    }
00204    ((TXTRU&)rhs).Copy(*this);
00205 
00206    return *this;
00207 }
00208 
00209 
00210 //______________________________________________________________________________
00211 void TXTRU::Copy(TObject &obj) const
00212 {
00213    // TXTRU Copy method
00214 
00215    // patterned after other ROOT objects
00216 
00217    TObject::Copy(obj);
00218    ((TXTRU&)obj).fNxy       = fNxy;
00219    ((TXTRU&)obj).fNxyAlloc  = fNxyAlloc;
00220    ((TXTRU&)obj).fXvtx = new Float_t [fNxyAlloc];
00221    ((TXTRU&)obj).fYvtx = new Float_t [fNxyAlloc];
00222    Int_t i = 0;
00223    for (i = 0; i < fNxyAlloc; i++) {
00224       ((TXTRU&)obj).fXvtx[i] = fXvtx[i];
00225       ((TXTRU&)obj).fYvtx[i] = fYvtx[i];
00226    }
00227 
00228    ((TXTRU&)obj).fNz       = fNz;
00229    ((TXTRU&)obj).fNzAlloc  = fNzAlloc;
00230    ((TXTRU&)obj).fZ     = new Float_t [fNzAlloc];
00231    ((TXTRU&)obj).fScale = new Float_t [fNzAlloc];
00232    ((TXTRU&)obj).fX0    = new Float_t [fNzAlloc];
00233    ((TXTRU&)obj).fY0    = new Float_t [fNzAlloc];
00234    Int_t j = 0;
00235    for (j = 0; j < fNzAlloc; j++) {
00236       ((TXTRU&)obj).fZ[j]     = fZ[j];
00237       ((TXTRU&)obj).fScale[j] = fScale[j];
00238       ((TXTRU&)obj).fX0[j]    = fX0[j];
00239       ((TXTRU&)obj).fY0[j]    = fY0[j];
00240    }
00241 
00242    ((TXTRU&)obj).fPolygonShape = fPolygonShape;
00243    ((TXTRU&)obj).fZOrdering    = fZOrdering;
00244 }
00245 
00246 
00247 //______________________________________________________________________________
00248 void TXTRU::DefineSection(Int_t iz, Float_t z, Float_t scale, Float_t x0, Float_t y0)
00249 {
00250    // Set z section iz information
00251    // expand size of array if necessary
00252 
00253    if (iz < 0) return;
00254 
00255    // setting a new section makes things unverified
00256    fZOrdering  = kUncheckedZ;
00257 
00258    if (iz >= fNzAlloc) {
00259       // re-allocate the z positions/scales
00260       Int_t   newNalloc = iz + 1;
00261       Float_t *newZ = new Float_t [newNalloc];
00262       Float_t *newS = new Float_t [newNalloc];
00263       Float_t *newX = new Float_t [newNalloc];
00264       Float_t *newY = new Float_t [newNalloc];
00265       Int_t i = 0;
00266       for (i = 0; i < newNalloc; i++) {
00267          if (i<fNz) {
00268             // copy the old points
00269             newZ[i] = fZ[i];
00270             newS[i] = fScale[i];
00271             newX[i] = fX0[i];
00272             newY[i] = fY0[i];
00273          } else {
00274             // zero out the new points
00275             newZ[i] = 0;
00276             newS[i] = 0;
00277             newX[i] = 0;
00278             newY[i] = 0;
00279          }
00280       }
00281       delete [] fZ;
00282       delete [] fScale;
00283       delete [] fX0;
00284       delete [] fY0;
00285       fZ     = newZ;
00286       fScale = newS;
00287       fX0    = newX;
00288       fY0    = newY;
00289       fNzAlloc = newNalloc;
00290    }
00291 
00292    // filled z "iz" means indices 0...iz have values -> iz+1 entries
00293    fNz = TMath::Max(iz+1,fNz);
00294 
00295    fZ[iz]     = z;
00296    fScale[iz] = scale;
00297    fX0[iz]    = x0;
00298    fY0[iz]    = y0;
00299 }
00300 
00301 
00302 //______________________________________________________________________________
00303 void TXTRU::DefineVertex(Int_t ipt, Float_t x, Float_t y) {
00304 
00305    // Set vertex point ipt to (x,y)
00306    // expand size of array if necessary
00307 
00308    if (ipt < 0) return;
00309 
00310    // setting a new vertex makes things unverified
00311    fPolygonShape  = kUncheckedXY;
00312 
00313    if (ipt >= fNxyAlloc) {
00314       // re-allocate the outline points
00315       Int_t   newNalloc = ipt + 1;
00316       Float_t *newX = new Float_t [newNalloc];
00317       Float_t *newY = new Float_t [newNalloc];
00318       Int_t i = 0;
00319       for (i = 0; i < newNalloc; i++) {
00320          if (i<fNxy) {
00321             // copy the old points
00322             newX[i] = fXvtx[i];
00323             newY[i] = fYvtx[i];
00324          } else {
00325             // zero out the new points
00326             newX[i] = 0;
00327             newY[i] = 0;
00328          }
00329       }
00330       delete [] fXvtx;
00331       delete [] fYvtx;
00332       fXvtx = newX;
00333       fYvtx = newY;
00334       fNxyAlloc = newNalloc;
00335    }
00336 
00337    // filled point "ipt" means indices 0...ipt have values -> ipt+1 entries
00338    fNxy = TMath::Max(ipt+1,fNxy);
00339 
00340    fXvtx[ipt] = x;
00341    fYvtx[ipt] = y;
00342 }
00343 
00344 
00345 //______________________________________________________________________________
00346 Int_t TXTRU::DistancetoPrimitive(Int_t px, Int_t py)
00347 {
00348    // Compute the distance from point px,py to a TXTRU
00349    // by calculating the closest approach to each corner
00350 
00351    Int_t numPoints = fNz*fNxy;
00352    return ShapeDistancetoPrimitive(numPoints,px,py);
00353 }
00354 
00355 
00356 //______________________________________________________________________________
00357 Float_t TXTRU::GetOutlinePointX(Int_t n) const {
00358 
00359    // Return x coordinate of a vertex point
00360 
00361    if ((n < 0) || (n >= fNxy)) {
00362       Error(fName,"no such point %d [of %d]",n,fNxy);
00363       return 0.0;
00364    }
00365    return fXvtx[n];
00366 }
00367 
00368 
00369 //______________________________________________________________________________
00370 Float_t TXTRU::GetOutlinePointY(Int_t n) const {
00371 
00372    // Return y coordinate of a vertex point
00373 
00374    if ((n < 0) || (n >= fNxy)) {
00375       Error(fName,"no such point %d [of %d]",n,fNxy);
00376       return 0.0;
00377    }
00378    return fYvtx[n];
00379 }
00380 
00381 
00382 //______________________________________________________________________________
00383 Float_t TXTRU::GetSectionX0(Int_t n) const {
00384 
00385    // Return x0 shift of a z section
00386 
00387    if ((n < 0) || (n >= fNz)) {
00388       Error(fName,"no such section %d [of %d]",n,fNz);
00389       return 0.0;
00390    }
00391    return fX0[n];
00392 }
00393 
00394 
00395 //______________________________________________________________________________
00396 Float_t TXTRU::GetSectionY0(Int_t n) const {
00397 
00398    // Return y0 shift of a z section
00399 
00400    if ((n < 0) || (n >= fNz)) {
00401       Error(fName,"no such section %d [of %d]",n,fNz);
00402       return 0.0;
00403    }
00404    return fY0[n];
00405 }
00406 
00407 
00408 //______________________________________________________________________________
00409 Float_t TXTRU::GetSectionScale(Int_t n) const {
00410 
00411    // Return scale factor for a z section
00412 
00413    if ((n < 0) || (n >= fNz)) {
00414       Error(fName,"no such section %d [of %d]",n,fNz);
00415       return 0.0;
00416    }
00417    return fScale[n];
00418 }
00419 
00420 
00421 //______________________________________________________________________________
00422 Float_t TXTRU::GetSectionZ(Int_t n) const {
00423 
00424    // Return z of a z section
00425 
00426    if ((n < 0) || (n >= fNz)) {
00427       Error(fName,"no such section %d [of %d]",n,fNz);
00428       return 0.0;
00429    }
00430    return fZ[n];
00431 }
00432 
00433 
00434 //______________________________________________________________________________
00435 void TXTRU::Print(Option_t *option) const
00436 {
00437    // Dump the info of this TXTRU shape
00438    // Option: "xy" to get x-y information
00439    //         "z"  to get z information
00440    //         "alloc" to show full allocated arrays (not just used values)
00441 
00442    TString opt = option;
00443    opt.ToLower();
00444 
00445    printf("TXTRU %s Nxy=%d [of %d] Nz=%d [of %d] Option=%s\n",
00446           GetName(),fNxy,fNxyAlloc,fNz,fNzAlloc,option);
00447 
00448    const char *shape = 0;
00449    const char *zorder = 0;
00450 
00451    switch (fPolygonShape) {
00452    case kUncheckedXY:   shape = "Unchecked  ";  break;
00453    case kMalformedXY:   shape = "Malformed  ";  break;
00454    case kConvexCCW:     shape = "Convex CCW ";  break;
00455    case kConvexCW:      shape = "Convex CW  ";  break;
00456    case kConcaveCCW:    shape = "Concave CCW";  break;
00457    case kConcaveCW:     shape = "Concave CW ";  break;
00458    }
00459 
00460    switch (fZOrdering) {
00461    case kUncheckedZ:    zorder = "Unchecked Z";  break;
00462    case kMalformedZ:    zorder = "Malformed Z";  break;
00463    case kConvexIncZ:    zorder = "Convex Increasing Z";  break;
00464    case kConvexDecZ:    zorder = "Convex Decreasing Z";  break;
00465    case kConcaveIncZ:   zorder = "Concave Increasing Z";  break;
00466    case kConcaveDecZ:   zorder = "Concave Decreasing Z";  break;
00467    }
00468 
00469    printf("  XY shape '%s', '%s'\n",shape,zorder);
00470 
00471    Int_t       nxy, nz;
00472 
00473    if (opt.Contains("alloc")) {
00474       nxy    = fNxy;
00475       nz     = fNz;
00476    } else {
00477       nxy    = fNxyAlloc;
00478       nz    = fNzAlloc;
00479    }
00480 
00481    const char *name;
00482    Float_t *p;
00483    Int_t   nlimit;
00484    Bool_t  print_vtx = opt.Contains("xy");
00485    Bool_t  print_z   = opt.Contains("z");
00486 
00487    Int_t ixyz=0;
00488    for (ixyz=0; ixyz<6; ixyz++) {
00489       switch (ixyz) {
00490       case 0: p = fXvtx;  name = "x";     nlimit = nxy; break;
00491       case 1: p = fYvtx;  name = "y";     nlimit = nxy; break;
00492       case 2: p = fZ;     name = "z";     nlimit = nz;  break;
00493       case 3: p = fScale; name = "scale"; nlimit = nz;  break;
00494       case 4: p = fX0;    name = "x0";    nlimit = nz;  break;
00495       case 5: p = fY0;    name = "y0";    nlimit = nz;  break;
00496       default: continue;
00497       }
00498       if (ixyz<=1 && !print_vtx) continue;
00499       if (ixyz>=2 && !print_z) continue;
00500 
00501       printf(" Float_t %s[] = \n    { %10g",name,*p++);
00502       Int_t i=1;
00503       for (i=1;i<nlimit;i++) {
00504          printf(", %10g",*p++);
00505          if (i%6==5) printf("\n    ");
00506       }
00507       printf(" };\n");
00508    }
00509 
00510 }
00511 
00512 
00513 //______________________________________________________________________________
00514 void TXTRU::SetPoints(Double_t *points) const
00515 {
00516    // Create TXTRU points in buffer
00517    // order as expected by other methods (counterclockwise xy, increasing z)
00518 
00519    if (points) {
00520       Int_t ipt, ixy, iz, ioff;
00521       Float_t x, y;
00522 
00523       // put xy in counterclockwise order
00524       Bool_t iscw = (fPolygonShape == kConvexCW ||
00525                      fPolygonShape == kConcaveCW  );
00526 
00527       // put z
00528       Bool_t reversez = (fZOrdering == kConvexDecZ ||
00529                          fZOrdering == kConcaveDecZ  );
00530 
00531       ipt = 0; // point number
00532       Int_t i=0;
00533       for (i=0; i<fNz; i++) {        // loop over sections
00534          iz = (reversez) ? fNz-1 - i : i;
00535          Int_t j=0;
00536          for (j=0; j<fNxy; j++) {    // loop over points in section
00537             ixy = (iscw) ? fNxy-1 - j : j;
00538             ioff = ipt*3;                  // 3 words per point (x,y,z)
00539             x = fXvtx[ixy];
00540             y = fYvtx[ixy];
00541             points[ioff  ] = x*fScale[iz] + fX0[iz];
00542             points[ioff+1] = y*fScale[iz] + fY0[iz];
00543             points[ioff+2] = fZ[iz];
00544             ipt++;
00545          }
00546       }
00547    }
00548 }
00549 
00550 
00551 //______________________________________________________________________________
00552 void TXTRU::Sizeof3D() const
00553 {
00554    // Return total X3D needed by TNode::ls (when called with option "x")
00555 
00556    gSize3D.numPoints += fNz*fNxy;
00557    gSize3D.numSegs   += (2*fNz-1)*fNxy;
00558    gSize3D.numPolys  += (fNz-1)*fNxy+2;
00559 }
00560 
00561 
00562 //______________________________________________________________________________
00563 void TXTRU::SplitConcavePolygon(Bool_t split)
00564 {
00565    // (Dis)Enable the splitting of concave polygon outlines into
00566    // multiple convex polygons.  This would make for better rendering
00567    // in solid mode, but introduces extra, potentially confusing, lines
00568    // in wireframe mode.
00569    // *** Not yet implemented ***
00570 
00571    fSplitConcave = split;
00572 
00573    // Not implemented yet
00574    if (split) {
00575       fSplitConcave = kFALSE;
00576       cout << TNamed::GetName()
00577            << " TXTRU::SplitConcavePolygon is not yet implemented" << endl;
00578    }
00579 
00580 }
00581 
00582 
00583 //______________________________________________________________________________
00584 void TXTRU::TruncateNxy(Int_t npts) {
00585 
00586    // Truncate the vertex list
00587 
00588    if ((npts < 0) || (npts > fNxy)) {
00589       Error(fName,"truncate to %d impossible on %d points",npts,fNxy);
00590       return;
00591    }
00592    fNxy = npts;
00593    return;
00594 }
00595 
00596 
00597 //______________________________________________________________________________
00598 void TXTRU::TruncateNz(Int_t nz) {
00599 
00600    // Truncate the z section list
00601 
00602    if ((nz < 0) || (nz > fNz)) {
00603       Error(fName,"truncate to %d impossible on %d points",nz,fNz);
00604       return;
00605    }
00606    fNz = nz;
00607    return;
00608 }
00609 
00610 
00611 //______________________________________________________________________________
00612 void TXTRU::CheckOrdering()
00613 {
00614    // Determine ordering over which to process points, segments, surfaces
00615    // so that they render correctly.  Generally this has to do
00616    // with getting outward normals in the hidden/solid surface case.
00617 
00618    Float_t plus, minus, zero;
00619 
00620    // Check on polygon's shape
00621    // Convex vs. Concave and ClockWise vs. Counter-ClockWise
00622    plus = minus = zero = 0;
00623    Int_t ixy=0;
00624    for (ixy=0; ixy<fNxy; ixy++) {
00625       // calculate the cross product of the two segments that
00626       // meet at vertex "ixy"
00627       // concave polygons have a mixture of + and - values
00628       Int_t ixyprev = (ixy + fNxy - 1)%fNxy;
00629       Int_t ixynext = (ixy + fNxy + 1)%fNxy;
00630 
00631       Float_t dxprev = fXvtx[ixy]     - fXvtx[ixyprev];
00632       Float_t dyprev = fYvtx[ixy]     - fYvtx[ixyprev];
00633       Float_t dxnext = fXvtx[ixynext] - fXvtx[ixy];
00634       Float_t dynext = fYvtx[ixynext] - fYvtx[ixy];
00635 
00636       Float_t xprod = dxprev*dynext - dxnext*dyprev;
00637 
00638       if (xprod > 0) {
00639          plus += xprod;
00640       } else if (xprod < 0) {
00641          minus -= xprod;
00642       } else {
00643          zero++;
00644       }
00645    }
00646 
00647    if (fNxy<3) {
00648       // no check yet written for checking that the segments don't cross
00649       fPolygonShape = kMalformedXY;
00650    } else {
00651       if (plus==0 || minus==0) {
00652          // convex polygons have all of one sign
00653          if (plus>minus) {
00654             fPolygonShape = kConvexCCW;
00655          } else {
00656             fPolygonShape = kConvexCW;
00657          }
00658       } else {
00659          // concave
00660          if (plus>minus) {
00661             fPolygonShape = kConcaveCCW;
00662          } else {
00663             fPolygonShape = kConcaveCW;
00664          }
00665       }
00666    }
00667 
00668    // Check on z ordering
00669    // Convex vs. Concave and increasing or decreasing in z
00670    plus = minus = zero = 0;
00671    Bool_t scaleSignChange = kFALSE;
00672    Int_t iz=0;
00673    for (iz=0; iz<fNz; iz++) {
00674       // calculate the cross product of the two segments that
00675       // meet at vertex "iz"
00676       // concave polygons have a mixture of + and - values
00677       Int_t izprev = (iz + fNz - 1)%fNz;
00678       Int_t iznext = (iz + fNz + 1)%fNz;
00679 
00680       Float_t dzprev = fZ[iz]         - fZ[izprev];
00681       Float_t dsprev = fScale[iz]     - fScale[izprev];
00682       Float_t dznext = fZ[iznext]     - fZ[iz];
00683       Float_t dsnext = fScale[iznext] - fScale[iz];
00684 
00685       // special cases for end faces
00686       if (iz==0) {
00687          dzprev = 0;
00688          dsprev = fScale[0];
00689       } else if (iz==fNz-1) {
00690          dznext = 0;
00691          dsnext = -fScale[iz];
00692       }
00693 
00694       Float_t xprod = dznext*dsprev - dzprev*dsnext;
00695 
00696       if (xprod > 0) {
00697          plus += xprod;
00698       } else if (xprod < 0) {
00699          minus -= xprod;
00700       } else {
00701          zero++;
00702       }
00703       // also check for scale factors that change sign...
00704       if (fScale[iz]*fScale[iznext] < 0) scaleSignChange = kTRUE;
00705    }
00706 
00707    if (fNz<1 || scaleSignChange) {
00708       // no check yet written for checking that the segments don't cross
00709       fZOrdering = kMalformedZ;
00710    } else {
00711       if (plus==0 || minus==0) {
00712          // convex polygons have all of one sign
00713          if (plus>minus) {
00714             fZOrdering = kConvexIncZ;
00715          } else {
00716             fZOrdering = kConvexDecZ;
00717          }
00718       } else {
00719          // concave
00720          if (plus>minus) {
00721             fZOrdering = kConcaveIncZ;
00722          } else {
00723             fZOrdering = kConcaveDecZ;
00724          }
00725       }
00726    }
00727 }
00728 
00729 
00730 //______________________________________________________________________________
00731 void TXTRU::DumpPoints(int npoints, float *pointbuff) const
00732 {
00733    // Dump the vertex points for visual inspection
00734 
00735    cout << "TXTRU::DumpPoints - " << npoints << " points" << endl;
00736    int ioff = 0;
00737    float x,y,z;
00738    int ipt=0;
00739    for (ipt=0; ipt<npoints; ipt++) {
00740       x = pointbuff[ioff++];
00741       y = pointbuff[ioff++];
00742       z = pointbuff[ioff++];
00743       printf(" [%4d] %6.1f %6.1f %6.1f \n",ipt,x,y,z);
00744    }
00745 }
00746 
00747 
00748 //______________________________________________________________________________
00749 void TXTRU::DumpSegments(int nsegments, int *segbuff) const
00750 {
00751    // Dump the segment info for visual inspection
00752 
00753    cout << "TXTRU::DumpSegments - " << nsegments << " segments" << endl;
00754    int ioff = 0;
00755    int icol, p1, p2;
00756    int iseg=0;
00757    for (iseg=0; iseg<nsegments; iseg++) {
00758       icol = segbuff[ioff++];
00759       p1   = segbuff[ioff++];
00760       p2   = segbuff[ioff++];
00761       printf(" [%4d] %3d (%4d,%4d)\n",iseg,icol,p1,p2);
00762    }
00763 }
00764 
00765 
00766 //______________________________________________________________________________
00767 void TXTRU::DumpPolygons(int npolygons, int *polybuff, int buffsize) const
00768 {
00769    // Dump the derived polygon info for visual inspection
00770 
00771    cout << "TXTRU::DumpPolygons - " << npolygons << " polygons" << endl;
00772    int ioff = 0;
00773    int icol, nseg, iseg;
00774    int ipoly=0;
00775    for (ipoly=0; ipoly<npolygons; ipoly++) {
00776       icol = polybuff[ioff++];
00777       nseg = polybuff[ioff++];
00778 #ifndef R__MACOSX
00779       cout << "  [" << setw(4) << ipoly << "] icol " << setw(3) << icol
00780            << " nseg " << setw(3) << nseg << "  (";
00781 #else
00782       printf(" [%d4] icol %d3 nseg %d3  (", ipoly, icol, nseg);
00783 #endif
00784       for (iseg=0; iseg<nseg-1; iseg++) {
00785          cout << polybuff[ioff++] << ",";
00786       }
00787       cout << polybuff[ioff++] << ")" << endl;
00788    }
00789    cout << " buffer size " << buffsize << " last used " << --ioff << endl;
00790 }
00791 
00792 
00793 //______________________________________________________________________________
00794 const TBuffer3D & TXTRU::GetBuffer3D(Int_t reqSections) const
00795 {
00796    // Get buffer 3d.
00797 
00798    static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00799 
00800    TShape::FillBuffer3D(buffer, reqSections);
00801 
00802    if (reqSections & TBuffer3D::kRawSizes) {
00803       // Check that the polygon is well formed
00804       // convex vs. concave, z ordered monotonically
00805 
00806       if (fPolygonShape == kUncheckedXY ||
00807           fZOrdering    == kUncheckedZ) {
00808          const_cast<TXTRU *>(this)->CheckOrdering();
00809       }
00810       Int_t nbPnts = fNz*fNxy;
00811       Int_t nbSegs = fNxy*(2*fNz-1);
00812       Int_t nbPols = fNxy*(fNz-1)+2;
00813       if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+fNxy))) {
00814          buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00815       }
00816    }
00817    if (reqSections & TBuffer3D::kRaw) {
00818       // Points
00819       SetPoints(buffer.fPnts);
00820       if (!buffer.fLocalFrame) {
00821          TransformPoints(buffer.fPnts, buffer.NbPnts());
00822       }
00823 
00824       Int_t c = GetBasicColor();
00825 
00826       Int_t i,j, k;
00827       Int_t indx, indx2;
00828       indx = indx2 = 0;
00829 
00830       // Segments
00831       for (i=0; i<fNz; i++) {
00832          // loop Z planes
00833          indx2 = i*fNxy;
00834          // loop polygon segments
00835          for (j=0; j<fNxy; j++) {
00836             k = (j+1)%fNxy;
00837             buffer.fSegs[indx++] = c;
00838             buffer.fSegs[indx++] = indx2+j;
00839             buffer.fSegs[indx++] = indx2+k;
00840          }
00841       } // total: fNz*fNxy polygon segments
00842       for (i=0; i<fNz-1; i++) {
00843          // loop Z planes
00844          indx2 = i*fNxy;
00845          // loop polygon segments
00846          for (j=0; j<fNxy; j++) {
00847             k = j + fNxy;
00848             buffer.fSegs[indx++] = c;
00849             buffer.fSegs[indx++] = indx2+j;
00850             buffer.fSegs[indx++] = indx2+k;
00851          }
00852       } // total (fNz-1)*fNxy lateral segments
00853 
00854             // Polygons
00855       indx = 0;
00856 
00857       // fill lateral polygons
00858       for (i=0; i<fNz-1; i++) {
00859          indx2 = i*fNxy;
00860          for (j=0; j<fNxy; j++) {
00861          k = (j+1)%fNxy;
00862          buffer.fPols[indx++] = c+j%3;
00863          buffer.fPols[indx++] = 4;
00864          buffer.fPols[indx++] = indx2+j;
00865          buffer.fPols[indx++] = fNz*fNxy+indx2+k;
00866          buffer.fPols[indx++] = indx2+fNxy+j;
00867          buffer.fPols[indx++] = fNz*fNxy+indx2+j;
00868          }
00869       } // total (fNz-1)*fNxy polys
00870       buffer.fPols[indx++] = c+2;
00871       buffer.fPols[indx++] = fNxy;
00872       indx2 = 0;
00873       for (j = fNxy - 1; j >= 0; --j) {
00874          buffer.fPols[indx++] = indx2+j;
00875       }
00876 
00877       buffer.fPols[indx++] = c;
00878       buffer.fPols[indx++] = fNxy;
00879       indx2 = (fNz-1)*fNxy;
00880     
00881       for (j=0; j<fNxy; j++) {
00882          buffer.fPols[indx++] = indx2+j;
00883       }
00884 
00885       buffer.SetSectionsValid(TBuffer3D::kRaw);
00886    }
00887 
00888    return buffer;
00889 }

Generated on Tue Jul 5 14:16:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1