// @(#)root/g3d:$Id$ // Author: Rene Brun , Olivier Couet 31/10/97 /************************************************************************* * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "Riostream.h" #include "TROOT.h" #include "TView.h" #include "TMarker3DBox.h" #include "TVirtualPad.h" #include "TH1.h" #include "TH3.h" #include "TBuffer3D.h" #include "TBuffer3DTypes.h" #include "TVirtualViewer3D.h" #include "TGeometry.h" #include "TClass.h" #include "TMath.h" #include ClassImp(TMarker3DBox) //______________________________________________________________________________ // Marker3DBox is a special 3-D marker designed for event display. // It has the following parameters: // fX; X coordinate of the center of the box // fY; Y coordinate of the center of the box // fZ; Z coordinate of the center of the box // fDx; half length in X // fDy; half length in Y // fDz; half length in Z // fTheta; Angle of box z axis with respect to main Z axis // fPhi; Angle of box x axis with respect to main Xaxis // fRefObject; A reference to an object // Begin_Html

End_Html //______________________________________________________________________________ TMarker3DBox::TMarker3DBox() { // Marker3DBox default constructor fRefObject = 0; fDx = 1; fDy = 1; fDz = 1; fX = 0; fY = 0; fZ = 0; fTheta = 0; fPhi = 0; SetBit(kTemporary,kFALSE); } //______________________________________________________________________________ TMarker3DBox::TMarker3DBox( Float_t x, Float_t y, Float_t z, Float_t dx, Float_t dy, Float_t dz, Float_t theta, Float_t phi) :TAttLine(1,1,1), TAttFill(1,0) { // Marker3DBox normal constructor fDx = dx; fDy = dy; fDz = dz; fX = x; fY = y; fZ = z; fTheta = theta; fPhi = phi; fRefObject = 0; SetBit(kTemporary,kFALSE); } //______________________________________________________________________________ TMarker3DBox::TMarker3DBox(const TMarker3DBox& m3d) : TObject(m3d), TAttLine(m3d), TAttFill(m3d), TAtt3D(m3d), fX(m3d.fX), fY(m3d.fY), fZ(m3d.fZ), fDx(m3d.fDx), fDy(m3d.fDy), fDz(m3d.fDz), fTheta(m3d.fTheta), fPhi(m3d.fPhi), fRefObject(m3d.fRefObject) { //copy constructor } //______________________________________________________________________________ TMarker3DBox& TMarker3DBox::operator=(const TMarker3DBox& m3d) { //assignement operator if(this!=&m3d) { TObject::operator=(m3d); TAttLine::operator=(m3d); TAttFill::operator=(m3d); TAtt3D::operator=(m3d); fX=m3d.fX; fY=m3d.fY; fZ=m3d.fZ; fDx=m3d.fDx; fDy=m3d.fDy; fDz=m3d.fDz; fTheta=m3d.fTheta; fPhi=m3d.fPhi; fRefObject=m3d.fRefObject; } return *this; } //______________________________________________________________________________ TMarker3DBox::~TMarker3DBox() { // Marker3DBox shape default destructor } //______________________________________________________________________________ Int_t TMarker3DBox::DistancetoPrimitive(Int_t px, Int_t py) { // Compute distance from point px,py to a Marker3DBox // // Compute the closest distance of approach from point px,py to each corner // point of the Marker3DBox. const Int_t numPoints = 8; Int_t dist = 9999; Double_t points[3*numPoints]; TView *view = gPad->GetView(); if (!view) return dist; const Int_t seg1[12] = {0,1,2,3,4,5,6,7,0,1,2,3}; const Int_t seg2[12] = {1,2,3,0,5,6,7,4,4,5,6,7}; SetPoints(points); Int_t i, i1, i2, dsegment; Double_t x1,y1,x2,y2; Double_t xndc[3]; for (i = 0; i < 12; i++) { i1 = 3*seg1[i]; view->WCtoNDC(&points[i1], xndc); x1 = xndc[0]; y1 = xndc[1]; i2 = 3*seg2[i]; view->WCtoNDC(&points[i2], xndc); x2 = xndc[0]; y2 = xndc[1]; dsegment = DistancetoLine(px,py,x1,y1,x2,y2); if (dsegment < dist) dist = dsegment; } if (dist < 5) { gPad->SetCursor(kCross); if (fRefObject) {gPad->SetSelected(fRefObject); return 0;} } return dist; } //______________________________________________________________________________ void TMarker3DBox::ExecuteEvent(Int_t event, Int_t px, Int_t py) { // Execute action corresponding to one event // // This member function must be implemented to realize the action // corresponding to the mouse click on the object in the window if (gPad->GetView()) gPad->GetView()->ExecuteRotateView(event, px, py); } //______________________________________________________________________________ void TMarker3DBox::Paint(Option_t * /* option */ ) { // Paint marker 3D box. static TBuffer3D buffer(TBuffer3DTypes::kGeneric); buffer.ClearSectionsValid(); // Section kCore // If we are just a temporary object then no 'real object' to // pass to viewer if (TestBit(kTemporary)) { buffer.fID = 0; } else { buffer.fID = this; } buffer.fColor = GetLineColor(); buffer.fTransparency = 0; buffer.fLocalFrame = kFALSE; buffer.SetSectionsValid(TBuffer3D::kCore); // We fill kCore and kRawSizes on first pass and try with viewer TVirtualViewer3D * viewer3D = gPad->GetViewer3D(); if (!viewer3D) return; Int_t reqSections = viewer3D->AddObject(buffer); if (reqSections == TBuffer3D::kNone) { return; } if (reqSections & TBuffer3D::kRawSizes) { Int_t nbPnts = 8; Int_t nbSegs = 12; Int_t nbPols = 6; if (!buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) { return; } buffer.SetSectionsValid(TBuffer3D::kRawSizes); } if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) { // Points SetPoints(buffer.fPnts); // Transform points if (gGeometry && !buffer.fLocalFrame) { Double_t dlocal[3]; Double_t dmaster[3]; for (UInt_t j=0; jLocal2Master(&dlocal[0],&dmaster[0]); buffer.fPnts[3*j] = dmaster[0]; buffer.fPnts[3*j+1] = dmaster[1]; buffer.fPnts[3*j+2] = dmaster[2]; } } // Basic colors: 0, 1, ... 8 Int_t c = (((GetLineColor()) %8) -1) * 4; if (c < 0) c = 0; // Segments buffer.fSegs[ 0] = c ; buffer.fSegs[ 1] = 0 ; buffer.fSegs[ 2] = 1; buffer.fSegs[ 3] = c+1 ; buffer.fSegs[ 4] = 1 ; buffer.fSegs[ 5] = 2; buffer.fSegs[ 6] = c+1 ; buffer.fSegs[ 7] = 2 ; buffer.fSegs[ 8] = 3; buffer.fSegs[ 9] = c ; buffer.fSegs[10] = 3 ; buffer.fSegs[11] = 0; buffer.fSegs[12] = c+2 ; buffer.fSegs[13] = 4 ; buffer.fSegs[14] = 5; buffer.fSegs[15] = c+2 ; buffer.fSegs[16] = 5 ; buffer.fSegs[17] = 6; buffer.fSegs[18] = c+3 ; buffer.fSegs[19] = 6 ; buffer.fSegs[20] = 7; buffer.fSegs[21] = c+3 ; buffer.fSegs[22] = 7 ; buffer.fSegs[23] = 4; buffer.fSegs[24] = c ; buffer.fSegs[25] = 0 ; buffer.fSegs[26] = 4; buffer.fSegs[27] = c+2 ; buffer.fSegs[28] = 1 ; buffer.fSegs[29] = 5; buffer.fSegs[30] = c+1 ; buffer.fSegs[31] = 2 ; buffer.fSegs[32] = 6; buffer.fSegs[33] = c+3 ; buffer.fSegs[34] = 3 ; buffer.fSegs[35] = 7; // Polygons buffer.fPols[ 0] = c ; buffer.fPols[ 1] = 4 ; buffer.fPols[ 2] = 0; buffer.fPols[ 3] = 9 ; buffer.fPols[ 4] = 4 ; buffer.fPols[ 5] = 8; buffer.fPols[ 6] = c+1 ; buffer.fPols[ 7] = 4 ; buffer.fPols[ 8] = 1; buffer.fPols[ 9] = 10 ; buffer.fPols[10] = 5 ; buffer.fPols[11] = 9; buffer.fPols[12] = c ; buffer.fPols[13] = 4 ; buffer.fPols[14] = 2; buffer.fPols[15] = 11 ; buffer.fPols[16] = 6 ; buffer.fPols[17] = 10; buffer.fPols[18] = c+1 ; buffer.fPols[19] = 4 ; buffer.fPols[20] = 3; buffer.fPols[21] = 8 ; buffer.fPols[22] = 7 ; buffer.fPols[23] = 11; buffer.fPols[24] = c+2 ; buffer.fPols[25] = 4 ; buffer.fPols[26] = 0; buffer.fPols[27] = 3 ; buffer.fPols[28] = 2 ; buffer.fPols[29] = 1; buffer.fPols[30] = c+3 ; buffer.fPols[31] = 4 ; buffer.fPols[32] = 4; buffer.fPols[33] = 5 ; buffer.fPols[34] = 6 ; buffer.fPols[35] = 7; buffer.SetSectionsValid(TBuffer3D::kRaw); TAttLine::Modify(); TAttFill::Modify(); } viewer3D->AddObject(buffer); } //______________________________________________________________________________ void TMarker3DBox::PaintH3(TH1 *h, Option_t *option) { // Paint 3-d histogram h with marker3dboxes Int_t bin,ix,iy,iz; Double_t xmin,xmax,ymin,ymax,zmin,zmax,wmin,wmax,w; TAxis *xaxis = h->GetXaxis(); TAxis *yaxis = h->GetYaxis(); TAxis *zaxis = h->GetZaxis(); //compute min and max of all cells wmin = wmax = 0; for (iz=zaxis->GetFirst();iz<=zaxis->GetLast();iz++) { for (iy=yaxis->GetFirst();iy<=yaxis->GetLast();iy++) { for (ix=xaxis->GetFirst();ix<=xaxis->GetLast();ix++) { bin = h->GetBin(ix,iy,iz); w = h->GetBinContent(bin); if (w > wmax) wmax = w; if (w < wmin) wmin = w; } } } //Create or modify 3-d view object TView *view = gPad->GetView(); if (!view) { gPad->Range(-1,-1,1,1); view = TView::CreateView(1,0,0); if (!view) return; } view->SetRange(xaxis->GetBinLowEdge(xaxis->GetFirst()), yaxis->GetBinLowEdge(yaxis->GetFirst()), zaxis->GetBinLowEdge(zaxis->GetFirst()), xaxis->GetBinUpEdge(xaxis->GetLast()), yaxis->GetBinUpEdge(yaxis->GetLast()), zaxis->GetBinUpEdge(zaxis->GetLast())); view->PadRange(gPad->GetFrameFillColor()); //Draw TMarker3DBox with size proportional to cell content TMarker3DBox m3; m3.SetBit(kTemporary,kTRUE); m3.SetRefObject(h); m3.SetDirection(0,0); m3.SetLineColor(h->GetMarkerColor()); Double_t scale; for (ix=xaxis->GetFirst();ix<=xaxis->GetLast();ix++) { xmin = h->GetXaxis()->GetBinLowEdge(ix); xmax = xmin + h->GetXaxis()->GetBinWidth(ix); for (iy=yaxis->GetFirst();iy<=yaxis->GetLast();iy++) { ymin = h->GetYaxis()->GetBinLowEdge(iy); ymax = ymin + h->GetYaxis()->GetBinWidth(iy); for (iz=zaxis->GetFirst();iz<=zaxis->GetLast();iz++) { zmin = h->GetZaxis()->GetBinLowEdge(iz); zmax = zmin + h->GetZaxis()->GetBinWidth(iz); bin = h->GetBin(ix,iy,iz); w = h->GetBinContent(bin); if (w == 0) continue; scale = (w-wmin)/(wmax-wmin); m3.SetPosition(0.5*(xmin+xmax),0.5*(ymin+ymax),0.5*(zmin+zmax)); m3.SetSize(scale*(xmax-xmin),scale*(ymax-ymin),scale*(zmax-zmin)); m3.Paint(option); } } } } //______________________________________________________________________________ void TMarker3DBox::SavePrimitive(ostream &out, Option_t * /*= ""*/) { // Save primitive as a C++ statement(s) on output stream out out<<" "<ClassSaved(TMarker3DBox::Class())) { out<<" "; } else { out<<" TMarker3DBox *"; } out<<"marker3DBox = new TMarker3DBox("<Draw();"< 1) { R__b.ReadClassBuffer(TMarker3DBox::Class(), this, R__v, R__s, R__c); return; } //====process old versions before automatic schema evolution TObject::Streamer(R__b); TAttLine::Streamer(R__b); TAttFill::Streamer(R__b); if (R__b.GetVersionOwner() > 22300) { TAtt3D::Streamer(R__b); } else { TAtt3D::Streamer(R__b); } R__b >> fX; R__b >> fY; R__b >> fZ; R__b >> fDx; R__b >> fDy; R__b >> fDz; R__b >> fTheta; R__b >> fPhi; R__b >> fRefObject; R__b.CheckByteCount(R__s, R__c, TMarker3DBox::IsA()); //====end of old versions } else { R__b.WriteClassBuffer(TMarker3DBox::Class(),this); } }