#include "QuadSet.h"
#include "RGBAPalette.h"
+#include "RGTopFrame.h"
#include <TColor.h>
TNamed(n, t),
fQuadType(QT_Undef),
- fValueIsColor(kFALSE),
fDefaultValue(kMinInt),
+ fValueIsColor(kFALSE),
+ fOwnIds (kFALSE),
fPlex(),
fLastQuad(0),
fFrame (0),
fPalette(0),
- fRenderMode(RM_AsIs),
+ fRenderMode(RM_Fill),
+ fDisableLigting(kTRUE),
+ fEmitSignals(kFALSE),
fHMTrans()
{}
TNamed(n, t),
fQuadType(quadType),
- fValueIsColor(valIsCol),
fDefaultValue(valIsCol ? 0 : kMinInt),
+ fValueIsColor(valIsCol),
+ fOwnIds (kFALSE),
fPlex(SizeofAtom(quadType), chunkSize),
fLastQuad(0),
fFrame (0),
fPalette(0),
- fRenderMode(RM_AsIs),
+ fRenderMode(RM_Fill),
+ fDisableLigting(kTRUE),
+ fEmitSignals(kFALSE),
fHMTrans()
{}
{
SetFrame(0);
SetPalette(0);
+ if (fOwnIds)
+ ReleaseIds();
+}
+
+void QuadSet::ReleaseIds()
+{
+ VoidCPlex::iterator qi(fPlex);
+ while (qi.next()) {
+ QuadBase& q = * (QuadBase*) qi();
+ if (q.fId.GetObject()) {
+ delete q.fId.GetObject();
+ q.fId = 0;
+ }
+ }
}
/**************************************************************************/
Int_t QuadSet::SizeofAtom(QuadSet::QuadType_e qt)
{
+ static const Exc_t eH("QuadSet::SizeofAtom ");
+
switch (qt) {
case QT_Undef: return 0;
- case QT_FreeQuad: return sizeof(FreeQuad);
- case QT_AxisAligned: return sizeof(AAQuad);
- case QT_AxisAlignedFixedDim: return sizeof(AAFixDimQuad);
- case QT_AxisAlignedFixedY:
- case QT_AxisAlignedFixedZ: return sizeof(AAFixZQuad);
- case QT_AxisAlignedFixedDimY:
- case QT_AxisAlignedFixedDimZ: return sizeof(AAFixDimZQuad);
- case QT_LineFixedY:
- case QT_LineFixedZ: return sizeof(LineFixedZ);
+ case QT_FreeQuad: return sizeof(QFreeQuad);
+ case QT_RectangleXY: return sizeof(QRect);
+ case QT_RectangleXYFixedDim: return sizeof(QRectFixDim);
+ case QT_RectangleXZFixedY:
+ case QT_RectangleXYFixedZ: return sizeof(QRectFixC);
+ case QT_RectangleXZFixedDimY:
+ case QT_RectangleXYFixedDimZ: return sizeof(QRectFixDimC);
+ case QT_LineXZFixedY:
+ case QT_LineXYFixedZ: return sizeof(QLineFixC);
+ case QT_HexagonXY:
+ case QT_HexagonYX: return sizeof(QHex);
+ default: throw(eH + "unexpected atom type.");
}
return 0;
}
fQuadType = quadType;
fValueIsColor = valIsCol;
fDefaultValue = valIsCol ? 0 : kMinInt;
+ if (fOwnIds)
+ ReleaseIds();
fPlex.Reset(SizeofAtom(fQuadType), chunkSize);
}
/**************************************************************************/
+void QuadSet::SetMainColor(Color_t color)
+{
+ if (fFrame) {
+ fFrame->SetFrameColor(color);
+ fFrame->UpdateBackPtrItems();
+ }
+ gReve->Redraw3D();
+}
+
void QuadSet::SetFrame(FrameBox* b)
{
if (fFrame == b) return;
- if (fFrame) fFrame->DecRefCount();
+ if (fFrame) fFrame->DecRefCount(this);
fFrame = b;
if (fFrame) {
- fFrame->IncRefCount();
+ fFrame->IncRefCount(this);
SetMainColorPtr(fFrame->PtrFrameColor());
} else {
SetMainColorPtr(0);
if (fPalette) fPalette->IncRefCount();
}
+RGBAPalette* QuadSet::AssertPalette()
+{
+ if (fPalette == 0) {
+ fPalette = new RGBAPalette;
+ if (!fValueIsColor) {
+ Int_t min, max;
+ ScanMinMaxValues(min, max);
+ fPalette->SetLimits(min, max);
+ fPalette->SetMinMax(min, max);
+ }
+ }
+ return fPalette;
+}
+
/**************************************************************************/
QuadSet::QuadBase* QuadSet::NewQuad()
void QuadSet::AddQuad(Float_t* verts)
{
static const Exc_t eH("QuadSet::AddQuad ");
+
if (fQuadType != QT_FreeQuad)
throw(eH + "expect free quad-type.");
- FreeQuad* fq = (FreeQuad*) NewQuad();
+ QFreeQuad* fq = (QFreeQuad*) NewQuad();
memcpy(fq->fVertices, verts, sizeof(fq->fVertices));
}
{
static const Exc_t eH("QuadSet::AddAAQuad ");
- AAFixDimZQuad& fq = * (AAFixDimZQuad*) NewQuad();
+ QOrigin& fq = * (QOrigin*) NewQuad();
fq.fX = x; fq.fY = y;
switch (fQuadType)
{
- case QT_AxisAligned: {
- AAQuad& q = (AAQuad&) fq;
+ case QT_RectangleXY: {
+ QRect& q = (QRect&) fq;
q.fZ = z; q.fW = w; q.fH = h;
break;
}
- case QT_AxisAlignedFixedDim: {
- AAFixDimQuad& q = (AAFixDimQuad&) fq;
+ case QT_RectangleXYFixedDim: {
+ QRectFixDim& q = (QRectFixDim&) fq;
q.fZ = z;
break;
}
- case QT_AxisAlignedFixedY:
- case QT_AxisAlignedFixedZ: {
- AAFixZQuad& q = (AAFixZQuad&) fq;
+ case QT_RectangleXZFixedY:
+ case QT_RectangleXYFixedZ: {
+ QRectFixC& q = (QRectFixC&) fq;
q.fW = w; q.fH = h;
break;
}
- case QT_AxisAlignedFixedDimY:
- case QT_AxisAlignedFixedDimZ: {
+ case QT_RectangleXZFixedDimY:
+ case QT_RectangleXYFixedDimZ: {
break;
}
- case QT_LineFixedY:
- case QT_LineFixedZ: {
- LineFixedZ& q = (LineFixedZ&) fq;
+ default:
+ throw(eH + "expect axis-aligned quad-type.");
+ }
+}
+
+void QuadSet::AddLine(Float_t x, Float_t y, Float_t w, Float_t h)
+{
+ static const Exc_t eH("QuadSet::AddLine ");
+
+ QOrigin& fq = * (QOrigin*) NewQuad();
+ fq.fX = x; fq.fY = y;
+ switch (fQuadType)
+ {
+ case QT_LineXZFixedY:
+ case QT_LineXYFixedZ: {
+ QLineFixC& q = (QLineFixC&) fq;
q.fDx = w; q.fDy = h;
break;
}
default:
- throw(eH + "expect axis-aligned quad-type.");
+ throw(eH + "expect line quad-type.");
+ }
+}
+
+void QuadSet::AddHexagon(Float_t x, Float_t y, Float_t z, Float_t r)
+{
+ static const Exc_t eH("QuadSet::AddHexagon ");
+
+ QOrigin& fq = * (QOrigin*) NewQuad();
+ fq.fX = x; fq.fY = y;
+ switch (fQuadType)
+ {
+ case QT_HexagonXY:
+ case QT_HexagonYX: {
+ QHex& q = (QHex&) fq;
+ q.fZ = z; q.fR = r;
+ break;
+ }
+ default:
+ throw(eH + "expect line quad-type.");
}
}
x[0] = r; x[1] = g; x[2] = b; x[3] = a;
}
-/**************************************************************************/
/**************************************************************************/
-void QuadSet::ComputeBBox()
+void QuadSet::QuadId(TObject* id)
{
- static const Exc_t eH("QuadSet::ComputeBBox ");
+ fLastQuad->fId = id;
+}
- // !!!! Missing handling of FrameBox !!!!
- // It shoud even simpify things ...
+/**************************************************************************/
- if(fPlex.Size() == 0) {
- BBoxZero();
- return;
+void QuadSet::QuadSelected(Int_t idx)
+{
+ if (fEmitSignals) {
+ CtrlClicked(this, idx);
+ } else {
+ QuadBase* qb = GetQuad(idx);
+ TObject* obj = qb->fId.GetObject();
+ printf("QuadSet::QuadSelected idx=%d, value=%d, obj=0x%lx\n",
+ idx, qb->fValue, (ULong_t)obj);
+ if (obj)
+ obj->Print();
}
+}
- BBoxInit();
- if (fQuadType == QT_AxisAlignedFixedZ ||
- fQuadType == QT_AxisAlignedFixedDimZ)
+void QuadSet::CtrlClicked(QuadSet* qs, Int_t idx)
+{
+ Long_t args[2];
+ args[0] = (Long_t) qs;
+ args[1] = (Long_t) idx;
+
+ Emit("CtrlClicked(Reve::Track*, Int_t)", args);
+}
+
+/**************************************************************************/
+/**************************************************************************/
+
+void QuadSet::ComputeBBox()
+{
+ // Fill bounding-box information in base-class TAttBBox (virtual method).
+ // If member 'FrameBox* fFrame' is set, frame's corners are used as bbox.
+
+ static const Exc_t eH("QuadSet::ComputeBBox ");
+
+ if (fFrame != 0)
{
- fBBox[4] = fDefCoord;
- fBBox[5] = fDefCoord;
+ 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 (fQuadType == QT_AxisAlignedFixedY ||
- fQuadType == QT_AxisAlignedFixedDimY)
+ else
{
- fBBox[2] = fDefCoord;
- fBBox[3] = fDefCoord;
- }
+ if(fPlex.Size() == 0) {
+ BBoxZero();
+ return;
+ }
- for (Int_t c=0; c<fPlex.VecSize(); ++c)
- {
- QuadBase* qbp = (QuadBase*) fPlex.Chunk(c);
- Int_t n = fPlex.NAtoms(c);
+ BBoxInit();
+ if (fQuadType == QT_RectangleXYFixedZ ||
+ fQuadType == QT_RectangleXYFixedDimZ)
+ {
+ fBBox[4] = fDefCoord;
+ fBBox[5] = fDefCoord;
+ }
+ else if (fQuadType == QT_RectangleXZFixedY ||
+ fQuadType == QT_RectangleXZFixedDimY)
+ {
+ fBBox[2] = fDefCoord;
+ fBBox[3] = fDefCoord;
+ }
+ VoidCPlex::iterator qi(fPlex);
+
switch (fQuadType)
{
case QT_FreeQuad:
{
- FreeQuad* qp = (FreeQuad*) qbp;
- while (n--) {
- Float_t* p = qp->fVertices;
+ while (qi.next()) {
+ const Float_t* p = ((QFreeQuad*) qi())->fVertices;
BBoxCheckPoint(p); p += 3;
BBoxCheckPoint(p); p += 3;
BBoxCheckPoint(p); p += 3;
BBoxCheckPoint(p);
- ++qp;
}
break;
}
- case QT_AxisAligned:
+ case QT_RectangleXY:
{
- AAQuad* qp = (AAQuad*) qbp;
- while (n--) {
- AAQuad& q = * qp;
+ while (qi.next()) {
+ QRect& q = * (QRect*) qi();
if(q.fX < fBBox[0]) fBBox[0] = q.fX;
if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
if(q.fY < fBBox[2]) fBBox[2] = q.fY;
if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
if(q.fZ < fBBox[4]) fBBox[4] = q.fZ;
if(q.fZ > fBBox[5]) fBBox[5] = q.fZ;
- ++qp;
}
break;
}
- case QT_AxisAlignedFixedDim:
+ case QT_RectangleXYFixedDim:
{
- AAFixDimQuad* qp = (AAFixDimQuad*) qbp;
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
- while (n--) {
- AAFixDimQuad& q = * qp;
+ while (qi.next()) {
+ QRectFixDim& q = * (QRectFixDim*) qi();
if(q.fX < fBBox[0]) fBBox[0] = q.fX;
if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
if(q.fY < fBBox[2]) fBBox[2] = q.fY;
if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
if(q.fZ < fBBox[4]) fBBox[4] = q.fZ;
if(q.fZ > fBBox[5]) fBBox[5] = q.fZ;
- ++qp;
}
break;
}
- case QT_AxisAlignedFixedZ:
+ case QT_RectangleXYFixedZ:
{
- AAFixZQuad* qp = (AAFixZQuad*) qbp;
- while (n--) {
- AAFixZQuad& q = * qp;
+ while (qi.next()) {
+ QRectFixC& q = * (QRectFixC*) qi();
if(q.fX < fBBox[0]) fBBox[0] = q.fX;
if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
if(q.fY < fBBox[2]) fBBox[2] = q.fY;
if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
- ++qp;
}
break;
}
- case QT_AxisAlignedFixedY:
+ case QT_RectangleXZFixedY:
{
- AAFixZQuad* qp = (AAFixZQuad*) qbp;
- while (n--) {
- AAFixZQuad& q = * qp;
+ while (qi.next()) {
+ QRectFixC& q = * (QRectFixC*) qi();
if(q.fX < fBBox[0]) fBBox[0] = q.fX;
if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
if(q.fY < fBBox[4]) fBBox[4] = q.fY;
if(q.fY + q.fH > fBBox[5]) fBBox[5] = q.fY + q.fH;
- ++qp;
}
break;
}
- case QT_AxisAlignedFixedDimZ:
+ case QT_RectangleXYFixedDimZ:
{
- AAFixDimZQuad* qp = (AAFixDimZQuad*) qbp;
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
- while (n--) {
- AAFixDimZQuad& q = * qp;
+ while (qi.next()) {
+ QRectFixDimC& q = * (QRectFixDimC*) qi();
if(q.fX < fBBox[0]) fBBox[0] = q.fX;
if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
if(q.fY < fBBox[2]) fBBox[2] = q.fY;
if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
- ++qp;
}
break;
}
- case QT_AxisAlignedFixedDimY:
+ case QT_RectangleXZFixedDimY:
{
- AAFixDimZQuad* qp = (AAFixDimZQuad*) qbp;
const Float_t& w = fDefWidth;
const Float_t& h = fDefHeight;
- while (n--) {
- AAFixDimZQuad& q = * qp;
+ while (qi.next()) {
+ QRectFixDimC& q = * (QRectFixDimC*) qi();
if(q.fX < fBBox[0]) fBBox[0] = q.fX;
if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
if(q.fY < fBBox[4]) fBBox[4] = q.fY;
if(q.fY + h > fBBox[5]) fBBox[5] = q.fY + h;
- ++qp;
}
break;
}
- case QT_LineFixedZ:
+ case QT_LineXYFixedZ:
{
- LineFixedZ* qp = (LineFixedZ*) qbp;
- while (n--) {
- LineFixedZ& q = * qp;
+ while (qi.next()) {
+ QLineFixC& q = * (QLineFixC*) qi();
BBoxCheckPoint(q.fX, q.fY, fDefCoord);
BBoxCheckPoint(q.fX + q.fDx, q.fY + q.fDy, fDefCoord);
- ++qp;
}
break;
}
- case QT_LineFixedY:
+ case QT_LineXZFixedY:
{
- LineFixedZ* qp = (LineFixedZ*) qbp;
- while (n--) {
- LineFixedZ& q = * qp;
+ while (qi.next()) {
+ QLineFixC& q = * (QLineFixC*) qi();
BBoxCheckPoint(q.fX, fDefCoord, q.fY);
BBoxCheckPoint(q.fX + q.fDx, fDefCoord, q.fY + q.fDy);
- ++qp;
+ }
+ break;
+ }
+
+ // Ignore 'slight' difference, assume square box for both cases.
+ case QT_HexagonXY:
+ case QT_HexagonYX:
+ {
+ while (qi.next()) {
+ QHex& q = * (QHex*) qi();
+ BBoxCheckPoint(q.fX-q.fR, q.fY-q.fR, q.fZ);
+ BBoxCheckPoint(q.fX+q.fR, q.fY+q.fR, q.fZ);
}
break;
}
}
} // end switch quad-type
-
- } // end for chunk
-
+ } // end if frame ... else ...
+
+#if ROOT_VERSION_CODE <= ROOT_VERSION(5,14,0)
+ { // Resize bounding box so that it does not have 0 volume.
+ // This should be done in TAttBBox (via method AssertMinExtents(epsilon)).
+ // Or handled more gracefully in TGLViewer.
+ static const Float_t eps = 1e-3;
+ for (Int_t i=0; i<6; i+=2) {
+ if (fBBox[i+1] - fBBox[i] < eps) {
+ Float_t b = 0.5*(fBBox[i] + fBBox[i+1]);
+ fBBox[i] = b - 0.5*eps;
+ fBBox[i+1] = b + 0.5*eps;
+ }
+ }
+ }
+#else
+ AssertBBoxExtents(0.001);
+#endif
}
/**************************************************************************/