#include "TXTRU.h"
#include "TVirtualPad.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TGeometry.h"
#include "TMath.h"
#include "Riostream.h"
ClassImp(TXTRU)
TXTRU::TXTRU()
   : fNxy(0), fNxyAlloc(0), fNz(0), fNzAlloc(0), fXvtx(0), fYvtx(0),
     fZ(0), fScale(0), fX0(0), fY0(0)
{
   
   fPolygonShape  = kUncheckedXY;
   fZOrdering     = kUncheckedZ;
}
TXTRU::TXTRU(const Text_t *name, const Text_t *title, const Text_t *material,
             Int_t nxy, Int_t nz)
   : TShape (name,title,material)
{
   
   
   
   
   
   fNxy      = 0;
   fNxyAlloc = 0;
   fNz       = 0;
   fNzAlloc  = 0;
   fXvtx     = 0;
   fYvtx     = 0;
   fZ        = 0;
   fScale    = 0;
   fX0       = 0;
   fY0       = 0;
   fPolygonShape  = kUncheckedXY;
   fZOrdering     = kUncheckedZ;
   if ( nxy < 3 ) {
      Error(name,"number of x-y points for %s must be at least three!",name);
      return;
   }
   if ( nz < 2 ) {
      Error(name,"number of z points for %s must be at least two!",name);
      return;
   }
   
   fNxy       = nxy;
   fNxyAlloc  = nxy;
   fXvtx      = new Float_t [fNxyAlloc];
   fYvtx      = new Float_t [fNxyAlloc];
   
   Int_t i = 0;
   for (i = 0; i < fNxyAlloc; i++) {
      fXvtx[i] = 0;
      fYvtx[i] = 0;
   }
   
   fNz        = nz;
   fNzAlloc   = nz;
   fZ         = new Float_t [fNzAlloc];
   fScale     = new Float_t [fNzAlloc];
   fX0        = new Float_t [fNzAlloc];
   fY0        = new Float_t [fNzAlloc];
   
   Int_t j = 0;
   for (j = 0; j < fNzAlloc; j++) {
      fZ[j]     = 0;
      fScale[j] = 0;
      fX0[j]    = 0;
      fY0[j]    = 0;
   }
}
TXTRU::TXTRU(const TXTRU &xtru) : TShape(xtru)
{
   
   
   ((TXTRU&)xtru).Copy(*this);
}
TXTRU::~TXTRU()
{
   
   if (fXvtx) delete [] fXvtx;
   if (fYvtx) delete [] fYvtx;
   fXvtx     = 0;
   fYvtx     = 0;
   fNxy      = 0;
   fNxyAlloc = 0;
   if (fZ)     delete [] fZ;
   if (fScale) delete [] fScale;
   if (fX0)    delete [] fX0;
   if (fY0)    delete [] fY0;
   fZ        = 0;
   fScale    = 0;
   fX0       = 0;
   fY0       = 0;
   fNz       = 0;
   fNzAlloc  = 0;
   fPolygonShape  = kUncheckedXY;
   fZOrdering     = kUncheckedZ;
}
TXTRU& TXTRU::operator=(const TXTRU &rhs)
{
   
   
   if (this == &rhs) return *this;
   if (fNxyAlloc) {
      delete [] fXvtx;
      delete [] fYvtx;
   }
   if (fNzAlloc) {
      delete [] fZ;
      delete [] fScale;
      delete [] fX0;
      delete [] fY0;
   }
   ((TXTRU&)rhs).Copy(*this);
   return *this;
}
void TXTRU::Copy(TObject &obj) const
{
   
   
   TObject::Copy(obj);
   ((TXTRU&)obj).fNxy       = fNxy;
   ((TXTRU&)obj).fNxyAlloc  = fNxyAlloc;
   ((TXTRU&)obj).fXvtx = new Float_t [fNxyAlloc];
   ((TXTRU&)obj).fYvtx = new Float_t [fNxyAlloc];
   Int_t i = 0;
   for (i = 0; i < fNxyAlloc; i++) {
      ((TXTRU&)obj).fXvtx[i] = fXvtx[i];
      ((TXTRU&)obj).fYvtx[i] = fYvtx[i];
   }
   ((TXTRU&)obj).fNz       = fNz;
   ((TXTRU&)obj).fNzAlloc  = fNzAlloc;
   ((TXTRU&)obj).fZ     = new Float_t [fNzAlloc];
   ((TXTRU&)obj).fScale = new Float_t [fNzAlloc];
   ((TXTRU&)obj).fX0    = new Float_t [fNzAlloc];
   ((TXTRU&)obj).fY0    = new Float_t [fNzAlloc];
   Int_t j = 0;
   for (j = 0; j < fNzAlloc; j++) {
      ((TXTRU&)obj).fZ[j]     = fZ[j];
      ((TXTRU&)obj).fScale[j] = fScale[j];
      ((TXTRU&)obj).fX0[j]    = fX0[j];
      ((TXTRU&)obj).fY0[j]    = fY0[j];
   }
   ((TXTRU&)obj).fPolygonShape = fPolygonShape;
   ((TXTRU&)obj).fZOrdering    = fZOrdering;
}
void TXTRU::DefineSection(Int_t iz, Float_t z, Float_t scale, Float_t x0, Float_t y0)
{
   
   
   if (iz < 0) return;
   
   fZOrdering  = kUncheckedZ;
   if (!fZ || !fScale || iz >= fNzAlloc) {
      
      Int_t   newNalloc = iz + 1;
      Float_t *newZ = new Float_t [newNalloc];
      Float_t *newS = new Float_t [newNalloc];
      Float_t *newX = new Float_t [newNalloc];
      Float_t *newY = new Float_t [newNalloc];
      Int_t i = 0;
      for (i = 0; i < newNalloc; i++) {
         if (i<fNz) {
            
            newZ[i] = fZ[i];
            newS[i] = fScale[i];
            newX[i] = fX0[i];
            newY[i] = fY0[i];
         } else {
            
            newZ[i] = 0;
            newS[i] = 0;
            newX[i] = 0;
            newY[i] = 0;
         }
      }
      delete [] fZ;
      delete [] fScale;
      delete [] fX0;
      delete [] fY0;
      fZ     = newZ;
      fScale = newS;
      fX0    = newX;
      fY0    = newY;
      fNzAlloc = newNalloc;
   }
   
   fNz = TMath::Max(iz+1,fNz);
   fZ[iz]     = z;
   fScale[iz] = scale;
   fX0[iz]    = x0;
   fY0[iz]    = y0;
}
void TXTRU::DefineVertex(Int_t ipt, Float_t x, Float_t y) {
   
   
   if (ipt < 0) return;
   
   fPolygonShape  = kUncheckedXY;
   if (!fXvtx || !fYvtx || ipt >= fNxyAlloc) {
      
      Int_t   newNalloc = ipt + 1;
      Float_t *newX = new Float_t [newNalloc];
      Float_t *newY = new Float_t [newNalloc];
      Int_t i = 0;
      for (i = 0; i < newNalloc; i++) {
         if (i<fNxy) {
            
            newX[i] = fXvtx[i];
            newY[i] = fYvtx[i];
         } else {
            
            newX[i] = 0;
            newY[i] = 0;
         }
      }
      delete [] fXvtx;
      delete [] fYvtx;
      fXvtx = newX;
      fYvtx = newY;
      fNxyAlloc = newNalloc;
   }
   
   fNxy = TMath::Max(ipt+1,fNxy);
   fXvtx[ipt] = x;
   fYvtx[ipt] = y;
}
Int_t TXTRU::DistancetoPrimitive(Int_t px, Int_t py)
{
   
   
   Int_t numPoints = fNz*fNxy;
   return ShapeDistancetoPrimitive(numPoints,px,py);
}
Float_t TXTRU::GetOutlinePointX(Int_t n) const {
   
   if ((n < 0) || (n >= fNxy)) {
      Error(fName,"no such point %d [of %d]",n,fNxy);
      return 0.0;
   }
   return fXvtx[n];
}
Float_t TXTRU::GetOutlinePointY(Int_t n) const {
   
   if ((n < 0) || (n >= fNxy)) {
      Error(fName,"no such point %d [of %d]",n,fNxy);
      return 0.0;
   }
   return fYvtx[n];
}
Float_t TXTRU::GetSectionX0(Int_t n) const {
   
   if ((n < 0) || (n >= fNz)) {
      Error(fName,"no such section %d [of %d]",n,fNz);
      return 0.0;
   }
   return fX0[n];
}
Float_t TXTRU::GetSectionY0(Int_t n) const {
   
   if ((n < 0) || (n >= fNz)) {
      Error(fName,"no such section %d [of %d]",n,fNz);
      return 0.0;
   }
   return fY0[n];
}
Float_t TXTRU::GetSectionScale(Int_t n) const {
   
   if ((n < 0) || (n >= fNz)) {
      Error(fName,"no such section %d [of %d]",n,fNz);
      return 0.0;
   }
   return fScale[n];
}
Float_t TXTRU::GetSectionZ(Int_t n) const {
   
   if ((n < 0) || (n >= fNz)) {
      Error(fName,"no such section %d [of %d]",n,fNz);
      return 0.0;
   }
   return fZ[n];
}
void TXTRU::Print(Option_t *option) const
{
   
   
   
   
   TString opt = option;
   opt.ToLower();
   printf("TXTRU %s Nxy=%d [of %d] Nz=%d [of %d] Option=%s\n",
          GetName(),fNxy,fNxyAlloc,fNz,fNzAlloc,option);
   const char *shape = 0;
   const char *zorder = 0;
   switch (fPolygonShape) {
   case kUncheckedXY:   shape = "Unchecked  ";  break;
   case kMalformedXY:   shape = "Malformed  ";  break;
   case kConvexCCW:     shape = "Convex CCW ";  break;
   case kConvexCW:      shape = "Convex CW  ";  break;
   case kConcaveCCW:    shape = "Concave CCW";  break;
   case kConcaveCW:     shape = "Concave CW ";  break;
   }
   switch (fZOrdering) {
   case kUncheckedZ:    zorder = "Unchecked Z";  break;
   case kMalformedZ:    zorder = "Malformed Z";  break;
   case kConvexIncZ:    zorder = "Convex Increasing Z";  break;
   case kConvexDecZ:    zorder = "Convex Decreasing Z";  break;
   case kConcaveIncZ:   zorder = "Concave Increasing Z";  break;
   case kConcaveDecZ:   zorder = "Concave Decreasing Z";  break;
   }
   printf("  XY shape '%s', '%s'\n",shape,zorder);
   Int_t       nxy, nz;
   if (opt.Contains("alloc")) {
      nxy    = fNxy;
      nz     = fNz;
   } else {
      nxy    = fNxyAlloc;
      nz    = fNzAlloc;
   }
   const char *name;
   Float_t *p;
   Int_t   nlimit;
   Bool_t  print_vtx = opt.Contains("xy");
   Bool_t  print_z   = opt.Contains("z");
   Int_t ixyz=0;
   for (ixyz=0; ixyz<6; ixyz++) {
      switch (ixyz) {
      case 0: p = fXvtx;  name = "x";     nlimit = nxy; break;
      case 1: p = fYvtx;  name = "y";     nlimit = nxy; break;
      case 2: p = fZ;     name = "z";     nlimit = nz;  break;
      case 3: p = fScale; name = "scale"; nlimit = nz;  break;
      case 4: p = fX0;    name = "x0";    nlimit = nz;  break;
      case 5: p = fY0;    name = "y0";    nlimit = nz;  break;
      default: continue;
      }
      if (ixyz<=1 && !print_vtx) continue;
      if (ixyz>=2 && !print_z) continue;
      printf(" Float_t %s[] = \n    { %10g",name,*p++);
      Int_t i=1;
      for (i=1;i<nlimit;i++) {
         printf(", %10g",*p++);
         if (i%6==5) printf("\n    ");
      }
      printf(" };\n");
   }
}
void TXTRU::SetPoints(Double_t *points) const
{
   
   
   if (points) {
      Int_t ipt, ixy, iz, ioff;
      Float_t x, y;
      
      Bool_t iscw = (fPolygonShape == kConvexCW ||
                     fPolygonShape == kConcaveCW  );
      
      Bool_t reversez = (fZOrdering == kConvexDecZ ||
                         fZOrdering == kConcaveDecZ  );
      ipt = 0; 
      Int_t i=0;
      for (i=0; i<fNz; i++) {        
         iz = (reversez) ? fNz-1 - i : i;
         Int_t j=0;
         for (j=0; j<fNxy; j++) {    
            ixy = (iscw) ? fNxy-1 - j : j;
            ioff = ipt*3;                  
            x = fXvtx[ixy];
            y = fYvtx[ixy];
            points[ioff  ] = x*fScale[iz] + fX0[iz];
            points[ioff+1] = y*fScale[iz] + fY0[iz];
            points[ioff+2] = fZ[iz];
            ipt++;
         }
      }
   }
}
void TXTRU::Sizeof3D() const
{
   
   gSize3D.numPoints += fNz*fNxy;
   gSize3D.numSegs   += (2*fNz-1)*fNxy;
   gSize3D.numPolys  += (fNz-1)*fNxy+2;
}
void TXTRU::SplitConcavePolygon(Bool_t split)
{
   
   
   
   
   
   fSplitConcave = split;
   
   if (split) {
      fSplitConcave = kFALSE;
      cout << TNamed::GetName()
           << " TXTRU::SplitConcavePolygon is not yet implemented" << endl;
   }
}
void TXTRU::TruncateNxy(Int_t npts) {
   
   if ((npts < 0) || (npts > fNxy)) {
      Error(fName,"truncate to %d impossible on %d points",npts,fNxy);
      return;
   }
   fNxy = npts;
   return;
}
void TXTRU::TruncateNz(Int_t nz) {
   
   if ((nz < 0) || (nz > fNz)) {
      Error(fName,"truncate to %d impossible on %d points",nz,fNz);
      return;
   }
   fNz = nz;
   return;
}
void TXTRU::CheckOrdering()
{
   
   
   
   Float_t plus, minus, zero;
   
   
   plus = minus = zero = 0;
   Int_t ixy=0;
   for (ixy=0; ixy<fNxy; ixy++) {
      
      
      
      Int_t ixyprev = (ixy + fNxy - 1)%fNxy;
      Int_t ixynext = (ixy + fNxy + 1)%fNxy;
      Float_t dxprev = fXvtx[ixy]     - fXvtx[ixyprev];
      Float_t dyprev = fYvtx[ixy]     - fYvtx[ixyprev];
      Float_t dxnext = fXvtx[ixynext] - fXvtx[ixy];
      Float_t dynext = fYvtx[ixynext] - fYvtx[ixy];
      Float_t xprod = dxprev*dynext - dxnext*dyprev;
      if (xprod > 0) {
         plus += xprod;
      } else if (xprod < 0) {
         minus -= xprod;
      } else {
         zero++;
      }
   }
   if (fNxy<3) {
      
      fPolygonShape = kMalformedXY;
   } else {
      if (plus==0 || minus==0) {
         
         if (plus>minus) {
            fPolygonShape = kConvexCCW;
         } else {
            fPolygonShape = kConvexCW;
         }
      } else {
         
         if (plus>minus) {
            fPolygonShape = kConcaveCCW;
         } else {
            fPolygonShape = kConcaveCW;
         }
      }
   }
   
   
   plus = minus = zero = 0;
   Bool_t scaleSignChange = kFALSE;
   Int_t iz=0;
   for (iz=0; iz<fNz; iz++) {
      
      
      
      Int_t izprev = (iz + fNz - 1)%fNz;
      Int_t iznext = (iz + fNz + 1)%fNz;
      Float_t dzprev = fZ[iz]         - fZ[izprev];
      Float_t dsprev = fScale[iz]     - fScale[izprev];
      Float_t dznext = fZ[iznext]     - fZ[iz];
      Float_t dsnext = fScale[iznext] - fScale[iz];
      
      if (iz==0) {
         dzprev = 0;
         dsprev = fScale[0];
      } else if (iz==fNz-1) {
         dznext = 0;
         dsnext = -fScale[iz];
      }
      Float_t xprod = dznext*dsprev - dzprev*dsnext;
      if (xprod > 0) {
         plus += xprod;
      } else if (xprod < 0) {
         minus -= xprod;
      } else {
         zero++;
      }
      
      if (fScale[iz]*fScale[iznext] < 0) scaleSignChange = kTRUE;
   }
   if (fNz<1 || scaleSignChange) {
      
      fZOrdering = kMalformedZ;
   } else {
      if (plus==0 || minus==0) {
         
         if (plus>minus) {
            fZOrdering = kConvexIncZ;
         } else {
            fZOrdering = kConvexDecZ;
         }
      } else {
         
         if (plus>minus) {
            fZOrdering = kConcaveIncZ;
         } else {
            fZOrdering = kConcaveDecZ;
         }
      }
   }
}
void TXTRU::DumpPoints(int npoints, float *pointbuff) const
{
   
   cout << "TXTRU::DumpPoints - " << npoints << " points" << endl;
   int ioff = 0;
   float x,y,z;
   int ipt=0;
   for (ipt=0; ipt<npoints; ipt++) {
      x = pointbuff[ioff++];
      y = pointbuff[ioff++];
      z = pointbuff[ioff++];
      printf(" [%4d] %6.1f %6.1f %6.1f \n",ipt,x,y,z);
   }
}
void TXTRU::DumpSegments(int nsegments, int *segbuff) const
{
   
   cout << "TXTRU::DumpSegments - " << nsegments << " segments" << endl;
   int ioff = 0;
   int icol, p1, p2;
   int iseg=0;
   for (iseg=0; iseg<nsegments; iseg++) {
      icol = segbuff[ioff++];
      p1   = segbuff[ioff++];
      p2   = segbuff[ioff++];
      printf(" [%4d] %3d (%4d,%4d)\n",iseg,icol,p1,p2);
   }
}
void TXTRU::DumpPolygons(int npolygons, int *polybuff, int buffsize) const
{
   
   cout << "TXTRU::DumpPolygons - " << npolygons << " polygons" << endl;
   int ioff = 0;
   int icol, nseg, iseg;
   int ipoly=0;
   for (ipoly=0; ipoly<npolygons; ipoly++) {
      icol = polybuff[ioff++];
      nseg = polybuff[ioff++];
#ifndef R__MACOSX
      cout << "  [" << setw(4) << ipoly << "] icol " << setw(3) << icol
           << " nseg " << setw(3) << nseg << "  (";
#else
      printf(" [%d4] icol %d3 nseg %d3  (", ipoly, icol, nseg);
#endif
      for (iseg=0; iseg<nseg-1; iseg++) {
         cout << polybuff[ioff++] << ",";
      }
      cout << polybuff[ioff++] << ")" << endl;
   }
   cout << " buffer size " << buffsize << " last used " << --ioff << endl;
}
const TBuffer3D & TXTRU::GetBuffer3D(Int_t reqSections) const
{
   
   static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
   TShape::FillBuffer3D(buffer, reqSections);
   if (reqSections & TBuffer3D::kRawSizes) {
      
      
      if (fPolygonShape == kUncheckedXY ||
          fZOrdering    == kUncheckedZ) {
         const_cast<TXTRU *>(this)->CheckOrdering();
      }
      Int_t nbPnts = fNz*fNxy;
      Int_t nbSegs = fNxy*(2*fNz-1);
      Int_t nbPols = fNxy*(fNz-1)+2;
      if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+fNxy))) {
         buffer.SetSectionsValid(TBuffer3D::kRawSizes);
      }
   }
   if (reqSections & TBuffer3D::kRaw) {
      
      SetPoints(buffer.fPnts);
      if (!buffer.fLocalFrame) {
         TransformPoints(buffer.fPnts, buffer.NbPnts());
      }
      Int_t c = GetBasicColor();
      Int_t i,j, k;
      Int_t indx, indx2;
      indx = indx2 = 0;
      
      for (i=0; i<fNz; i++) {
         
         indx2 = i*fNxy;
         
         for (j=0; j<fNxy; j++) {
            k = (j+1)%fNxy;
            buffer.fSegs[indx++] = c;
            buffer.fSegs[indx++] = indx2+j;
            buffer.fSegs[indx++] = indx2+k;
         }
      } 
      for (i=0; i<fNz-1; i++) {
         
         indx2 = i*fNxy;
         
         for (j=0; j<fNxy; j++) {
            k = j + fNxy;
            buffer.fSegs[indx++] = c;
            buffer.fSegs[indx++] = indx2+j;
            buffer.fSegs[indx++] = indx2+k;
         }
      } 
            
      indx = 0;
      
      for (i=0; i<fNz-1; i++) {
         indx2 = i*fNxy;
         for (j=0; j<fNxy; j++) {
         k = (j+1)%fNxy;
         buffer.fPols[indx++] = c+j%3;
         buffer.fPols[indx++] = 4;
         buffer.fPols[indx++] = indx2+j;
         buffer.fPols[indx++] = fNz*fNxy+indx2+k;
         buffer.fPols[indx++] = indx2+fNxy+j;
         buffer.fPols[indx++] = fNz*fNxy+indx2+j;
         }
      } 
      buffer.fPols[indx++] = c+2;
      buffer.fPols[indx++] = fNxy;
      indx2 = 0;
      for (j = fNxy - 1; j >= 0; --j) {
         buffer.fPols[indx++] = indx2+j;
      }
      buffer.fPols[indx++] = c;
      buffer.fPols[indx++] = fNxy;
      indx2 = (fNz-1)*fNxy;
    
      for (j=0; j<fNxy; j++) {
         buffer.fPols[indx++] = indx2+j;
      }
      buffer.SetSectionsValid(TBuffer3D::kRaw);
   }
   return buffer;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.