#include "TEveQuadSet.h"
#include "TEveManager.h"
#include "TColor.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"
#include "TROOT.h"
#include "TRandom.h"
ClassImp(TEveQuadSet);
TEveQuadSet::TEveQuadSet(const char* n, const char* t) :
TEveDigitSet (n, t),
fQuadType (kQT_Undef),
fDefWidth (1),
fDefHeight (1),
fDefCoord (0)
{
}
TEveQuadSet::TEveQuadSet(EQuadType_e quadType, Bool_t valIsCol, Int_t chunkSize,
const char* n, const char* t) :
TEveDigitSet (n, t),
fQuadType (kQT_Undef),
fDefWidth (1),
fDefHeight (1),
fDefCoord (0)
{
Reset(quadType, valIsCol, chunkSize);
}
Int_t TEveQuadSet::SizeofAtom(TEveQuadSet::EQuadType_e qt)
{
static const TEveException eH("TEveQuadSet::SizeofAtom ");
switch (qt) {
case kQT_Undef: return 0;
case kQT_FreeQuad: return sizeof(QFreeQuad_t);
case kQT_RectangleXY:
case kQT_RectangleXZ:
case kQT_RectangleYZ: return sizeof(QRect_t);
case kQT_RectangleXYFixedDim: return sizeof(QRectFixDim_t);
case kQT_RectangleXYFixedZ:
case kQT_RectangleXZFixedY:
case kQT_RectangleYZFixedX: return sizeof(QRectFixC_t);
case kQT_RectangleXYFixedDimZ:
case kQT_RectangleXZFixedDimY:
case kQT_RectangleYZFixedDimX: return sizeof(QRectFixDimC_t);
case kQT_LineXZFixedY:
case kQT_LineXYFixedZ: return sizeof(QLineFixC_t);
case kQT_HexagonXY:
case kQT_HexagonYX: return sizeof(QHex_t);
default: throw(eH + "unexpected atom type.");
}
return 0;
}
void TEveQuadSet::Reset(TEveQuadSet::EQuadType_e quadType, Bool_t valIsCol,
Int_t chunkSize)
{
fQuadType = quadType;
fValueIsColor = valIsCol;
fDefaultValue = valIsCol ? 0 : kMinInt;
if (fOwnIds)
ReleaseIds();
fPlex.Reset(SizeofAtom(fQuadType), chunkSize);
}
void TEveQuadSet::AddQuad(Float_t verts[12])
{
static const TEveException eH("TEveQuadSet::AddQuad ");
if (fQuadType != kQT_FreeQuad)
throw(eH + "expect free quad-type.");
QFreeQuad_t* fq = (QFreeQuad_t*) NewDigit();
if (verts != 0)
memcpy(fq->fVertices, verts, sizeof(fq->fVertices));
}
void TEveQuadSet::AddQuad(Float_t a, Float_t b)
{
AddQuad(a, b, fDefCoord, fDefWidth, fDefHeight);
}
void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t c)
{
AddQuad(a, b, c, fDefWidth, fDefHeight);
}
void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t w, Float_t h)
{
AddQuad(a, b, fDefCoord, w, h);
}
void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h)
{
static const TEveException eH("TEveQuadSet::AddAAQuad ");
QOrigin_t& fq = * (QOrigin_t*) NewDigit();
fq.fA = a; fq.fB = b;
switch (fQuadType)
{
case kQT_RectangleXY:
case kQT_RectangleXZ:
case kQT_RectangleYZ:
{
QRect_t& q = (QRect_t&) fq;
q.fC = c; q.fW = w; q.fH = h;
break;
}
case kQT_RectangleXYFixedDim:
{
QRectFixDim_t& q = (QRectFixDim_t&) fq;
q.fC = c;
break;
}
case kQT_RectangleXYFixedZ:
case kQT_RectangleXZFixedY:
case kQT_RectangleYZFixedX:
{
QRectFixC_t& q = (QRectFixC_t&) fq;
q.fW = w; q.fH = h;
break;
}
case kQT_RectangleXYFixedDimZ:
case kQT_RectangleXZFixedDimY:
case kQT_RectangleYZFixedDimX:
{
break;
}
default:
throw(eH + "expect axis-aligned quad-type.");
}
}
void TEveQuadSet::AddLine(Float_t a, Float_t b, Float_t w, Float_t h)
{
static const TEveException eH("TEveQuadSet::AddLine ");
QOrigin_t& fq = * (QOrigin_t*) NewDigit();
fq.fA = a; fq.fB = b;
switch (fQuadType)
{
case kQT_LineXZFixedY:
case kQT_LineXYFixedZ: {
QLineFixC_t& q = (QLineFixC_t&) fq;
q.fDx = w; q.fDy = h;
break;
}
default:
throw(eH + "expect line quad-type.");
}
}
void TEveQuadSet::AddHexagon(Float_t a, Float_t b, Float_t c, Float_t r)
{
static const TEveException eH("TEveQuadSet::AddHexagon ");
QOrigin_t& fq = * (QOrigin_t*) NewDigit();
fq.fA = a; fq.fB = b;
switch (fQuadType)
{
case kQT_HexagonXY:
case kQT_HexagonYX: {
QHex_t& q = (QHex_t&) fq;
q.fC = c; q.fR = r;
break;
}
default:
throw(eH + "expect line quad-type.");
}
}
void TEveQuadSet::ComputeBBox()
{
static const TEveException eH("TEveQuadSet::ComputeBBox ");
if (fFrame != 0)
{
BBoxInit();
Int_t n = fFrame->GetFrameSize() / 3;
Float_t *bbps = fFrame->GetFramePoints();
for (int i=0; i<n; ++i, bbps+=3)
BBoxCheckPoint(bbps);
}
else
{
if(fPlex.Size() == 0) {
BBoxZero();
return;
}
BBoxInit();
if (fQuadType == kQT_RectangleXYFixedZ ||
fQuadType == kQT_RectangleXYFixedDimZ)
{
fBBox[4] = fDefCoord;
fBBox[5] = fDefCoord;
}
else if (fQuadType == kQT_RectangleXZFixedY ||
fQuadType == kQT_RectangleXZFixedDimY)
{
fBBox[2] = fDefCoord;
fBBox[3] = fDefCoord;
}
else if (fQuadType == kQT_RectangleYZFixedX ||
fQuadType == kQT_RectangleYZFixedDimX)
{
fBBox[0] = fDefCoord;
fBBox[1] = fDefCoord;
}
TEveChunkManager::iterator qi(fPlex);
switch (fQuadType)
{
case kQT_FreeQuad:
{
while (qi.next()) {
const Float_t* p = ((QFreeQuad_t*) qi())->fVertices;
BBoxCheckPoint(p); p += 3;
BBoxCheckPoint(p); p += 3;
BBoxCheckPoint(p); p += 3;
BBoxCheckPoint(p);
}
break;
}
case kQT_RectangleXY:
{
while (qi.next()) {
QRect_t& q = * (QRect_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
if(q.fB < fBBox[2]) fBBox[2] = q.fB;
if(q.fB + q.fH > fBBox[3]) fBBox[3] = q.fB + q.fH;
if(q.fC < fBBox[4]) fBBox[4] = q.fC;
if(q.fC > fBBox[5]) fBBox[5] = q.fC;
}
break;
}
case kQT_RectangleXZ:
{
while (qi.next()) {
QRect_t& q = * (QRect_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
if(q.fB < fBBox[4]) fBBox[4] = q.fB;
if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
if(q.fC < fBBox[2]) fBBox[2] = q.fC;
if(q.fC > fBBox[3]) fBBox[3] = q.fC;
}
break;
}
case kQT_RectangleYZ:
{
while (qi.next()) {
QRect_t& q = * (QRect_t*) qi();
if(q.fA < fBBox[2]) fBBox[2] = q.fA;
if(q.fA + q.fW > fBBox[3]) fBBox[3] = q.fA + q.fW;
if(q.fB < fBBox[4]) fBBox[4] = q.fB;
if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
if(q.fC < fBBox[0]) fBBox[0] = q.fC;
if(q.fC > fBBox[1]) fBBox[1] = q.fC;
}
break;
}
case kQT_RectangleXYFixedDim:
{
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
while (qi.next()) {
QRectFixDim_t& q = * (QRectFixDim_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w;
if(q.fB < fBBox[2]) fBBox[2] = q.fB;
if(q.fB + h > fBBox[3]) fBBox[3] = q.fB + h;
if(q.fC < fBBox[4]) fBBox[4] = q.fC;
if(q.fC > fBBox[5]) fBBox[5] = q.fC;
}
break;
}
case kQT_RectangleXYFixedZ:
{
while (qi.next()) {
QRectFixC_t& q = * (QRectFixC_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
if(q.fB < fBBox[2]) fBBox[2] = q.fB;
if(q.fB + q.fH > fBBox[3]) fBBox[3] = q.fB + q.fH;
}
break;
}
case kQT_RectangleXZFixedY:
{
while (qi.next()) {
QRectFixC_t& q = * (QRectFixC_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW;
if(q.fB < fBBox[4]) fBBox[4] = q.fB;
if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
}
break;
}
case kQT_RectangleYZFixedX:
{
while (qi.next()) {
QRectFixC_t& q = * (QRectFixC_t*) qi();
if(q.fA < fBBox[2]) fBBox[2] = q.fA;
if(q.fA + q.fW > fBBox[3]) fBBox[3] = q.fA + q.fW;
if(q.fB < fBBox[4]) fBBox[4] = q.fB;
if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH;
}
break;
}
case kQT_RectangleXYFixedDimZ:
{
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
while (qi.next()) {
QRectFixDimC_t& q = * (QRectFixDimC_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w;
if(q.fB < fBBox[2]) fBBox[2] = q.fB;
if(q.fB + h > fBBox[3]) fBBox[3] = q.fB + h;
}
break;
}
case kQT_RectangleXZFixedDimY:
{
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
while (qi.next()) {
QRectFixDimC_t& q = * (QRectFixDimC_t*) qi();
if(q.fA < fBBox[0]) fBBox[0] = q.fA;
if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w;
if(q.fB < fBBox[4]) fBBox[4] = q.fB;
if(q.fB + h > fBBox[5]) fBBox[5] = q.fB + h;
}
break;
}
case kQT_RectangleYZFixedDimX:
{
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
while (qi.next()) {
QRectFixDimC_t& q = * (QRectFixDimC_t*) qi();
if(q.fA < fBBox[2]) fBBox[2] = q.fA;
if(q.fA + w > fBBox[3]) fBBox[3] = q.fA + w;
if(q.fB < fBBox[4]) fBBox[4] = q.fB;
if(q.fB + h > fBBox[5]) fBBox[5] = q.fB + h;
}
break;
}
case kQT_LineXYFixedZ:
{
while (qi.next()) {
QLineFixC_t& q = * (QLineFixC_t*) qi();
BBoxCheckPoint(q.fA, q.fB, fDefCoord);
BBoxCheckPoint(q.fA + q.fDx, q.fB + q.fDy, fDefCoord);
}
break;
}
case kQT_LineXZFixedY:
{
while (qi.next()) {
QLineFixC_t& q = * (QLineFixC_t*) qi();
BBoxCheckPoint(q.fA, fDefCoord, q.fB);
BBoxCheckPoint(q.fA + q.fDx, fDefCoord, q.fB + q.fDy);
}
break;
}
case kQT_HexagonXY:
case kQT_HexagonYX:
{
while (qi.next()) {
QHex_t& q = * (QHex_t*) qi();
BBoxCheckPoint(q.fA-q.fR, q.fB-q.fR, q.fC);
BBoxCheckPoint(q.fA+q.fR, q.fB+q.fR, q.fC);
}
break;
}
default:
{
throw(eH + "unsupported quad-type.");
}
}
}
}