diff --git a/graf3d/eve/inc/LinkDef.h b/graf3d/eve/inc/LinkDef.h index 3ae26cc05ce4281888d5b3bae4116338a5579cc3..0b43da36848b2b3323211a7b5c406ae727c84a1f 100644 --- a/graf3d/eve/inc/LinkDef.h +++ b/graf3d/eve/inc/LinkDef.h @@ -191,6 +191,11 @@ #pragma link C++ class TEveProjectable+; #pragma link C++ class TEveProjected+; #pragma link C++ class TEveProjection+; +#pragma link C++ class TEveProjection::PreScaleEntry_t+; +#pragma link C++ class std::vector<TEveProjection::PreScaleEntry_t>; +#pragma link C++ class std::vector<TEveProjection::PreScaleEntry_t>::iterator; +#pragma link C++ typedef TEveProjection::vPreScale_t; +#pragma link C++ typedef TEveProjection::vPreScale_i; #pragma link C++ class TEveRhoZProjection+; #pragma link C++ class TEveRPhiProjection+; diff --git a/graf3d/eve/inc/TEveProjectionManager.h b/graf3d/eve/inc/TEveProjectionManager.h index 4826abb190c016fb89e1f9cf8398ff1000764b30..1c2a454c0eee67b456ea1bb62ab74a0ba59ac658 100644 --- a/graf3d/eve/inc/TEveProjectionManager.h +++ b/graf3d/eve/inc/TEveProjectionManager.h @@ -26,7 +26,9 @@ private: TEveProjectionManager& operator=(const TEveProjectionManager&); // Not implemented protected: - TEveProjection* fProjection; // projection + TEveProjection* fProjections[TEveProjection::kPT_End]; + + TEveProjection* fProjection; // current projection TEveVector fCenter; // center of distortion Float_t fCurrentDepth; // z depth of object being projected @@ -44,7 +46,7 @@ public: void AddDependent(TEveElement* el); void RemoveDependent(TEveElement* el); - void SetProjection(TEveProjection::EPType_e type, Float_t distort=0); + void SetProjection(TEveProjection::EPType_e type); TEveProjection* GetProjection() { return fProjection; } virtual void UpdateName(); diff --git a/graf3d/eve/inc/TEveProjections.h b/graf3d/eve/inc/TEveProjections.h index f835559acd9c015a336a959cb6e3d80e7de1ecfa..c3da8e4425563e86289bdbab26cb86760f69b4dc 100644 --- a/graf3d/eve/inc/TEveProjections.h +++ b/graf3d/eve/inc/TEveProjections.h @@ -14,6 +14,8 @@ #include "TEveVSDStructs.h" +#include <vector> + //////////////////////////////////////////////////////////////// // // // TEveProjection // @@ -23,10 +25,29 @@ class TEveProjection { public: - enum EPType_e { kPT_Unknown, kPT_RPhi, kPT_RhoZ }; // type + enum EPType_e { kPT_Unknown, kPT_RPhi, kPT_RhoZ, kPT_End };// type enum EPProc_e { kPP_Plane, kPP_Distort, kPP_Full }; // procedure enum EGeoMode_e { kGM_Unknown, kGM_Polygons, kGM_Segments }; // reconstruction of geometry + struct PreScaleEntry_t + { + Float_t fMin, fMax; + Float_t fOffset; + Float_t fScale; + + PreScaleEntry_t() : + fMin(0), fMax(0), fOffset(0), fScale(1) {} + PreScaleEntry_t(Float_t min, Float_t max, Float_t off, Float_t scale) : + fMin(min), fMax(max), fOffset(off), fScale(scale) {} + + virtual ~PreScaleEntry_t() {} + + ClassDef(PreScaleEntry_t, 0); + }; + + typedef std::vector<PreScaleEntry_t> vPreScale_t; + typedef std::vector<PreScaleEntry_t>::iterator vPreScale_i; + protected: EPType_e fType; // type EGeoMode_e fGeoMode; // strategy of polygon projection (what to try first) @@ -35,6 +56,9 @@ protected: TEveVector fCenter; // center of distortion TEveVector fZeroPosVal; // projected origin (0, 0, 0) + Bool_t fUsePreScale; // use pre-scaling + vPreScale_t fPreScales[2]; // scaling before the distortion + Float_t fDistortion; // distortion Float_t fFixR; // radius from which scaling remains constant Float_t fFixZ; // z-coordinate from which scaling remains constant @@ -49,7 +73,7 @@ protected: TEveVector fUpLimit; // convergence of point -infinity public: - TEveProjection(TEveVector& center); + TEveProjection(); virtual ~TEveProjection() {} virtual void ProjectPoint(Float_t&, Float_t&, Float_t&, EPProc_e p = kPP_Full ) = 0; @@ -70,6 +94,13 @@ public: virtual void UpdateLimit(); + Bool_t GetUsePreScale() const { return fUsePreScale; } + void SetUsePreScale(Bool_t x) { fUsePreScale = x; } + + void PreScalePoint(Float_t& x, Float_t& y); + void AddPreScaleEntry(Int_t coord, Float_t max_val, Float_t scale); + void ClearPreScales(); + void SetDistortion(Float_t d); Float_t GetDistortion() const { return fDistortion; } Float_t GetFixR() const { return fFixR; } @@ -107,7 +138,7 @@ private: TEveVector fProjectedCenter; // projected center of distortion. public: - TEveRhoZProjection(TEveVector& center); + TEveRhoZProjection(); virtual ~TEveRhoZProjection() {} virtual void ProjectPoint(Float_t& x, Float_t& y, Float_t& z, EPProc_e proc = kPP_Full); @@ -133,7 +164,7 @@ public: class TEveRPhiProjection : public TEveProjection { public: - TEveRPhiProjection(TEveVector& center); + TEveRPhiProjection(); virtual ~TEveRPhiProjection() {} virtual void ProjectPoint(Float_t& x, Float_t& y, Float_t& z, EPProc_e proc = kPP_Full); diff --git a/graf3d/eve/src/TEveProjectionManager.cxx b/graf3d/eve/src/TEveProjectionManager.cxx index 5e9e93c733443c9e10a28f038fd362ba9dcbc819..d37773709395dda05e0f9175e9ee1fb6d65ce734 100644 --- a/graf3d/eve/src/TEveProjectionManager.cxx +++ b/graf3d/eve/src/TEveProjectionManager.cxx @@ -50,8 +50,9 @@ TEveProjectionManager::TEveProjectionManager(): { // Constructor. - fProjection = new TEveRPhiProjection(fCenter); - UpdateName(); + for (Int_t i = 0; i < TEveProjection::kPT_End; ++i) + fProjections[i] = 0; + SetProjection(TEveProjection::kPT_RPhi); } //______________________________________________________________________________ @@ -60,7 +61,10 @@ TEveProjectionManager::~TEveProjectionManager() // Destructor. // Destroys also dependent elements. - if (fProjection) delete fProjection; + for (Int_t i = 0; i < TEveProjection::kPT_End; ++i) + { + delete fProjections[i]; + } while ( ! fDependentEls.empty()) { fDependentEls.front()->Destroy(); @@ -92,32 +96,33 @@ void TEveProjectionManager::UpdateName() } //______________________________________________________________________________ -void TEveProjectionManager::SetProjection(TEveProjection::EPType_e type, Float_t distort) +void TEveProjectionManager::SetProjection(TEveProjection::EPType_e type) { // Set projection type and distortion. static const TEveException eH("TEveProjectionManager::SetProjection "); - delete fProjection; - fProjection = 0; - - switch (type) + if (fProjections[type] == 0) { - case TEveProjection::kPT_RPhi: + switch (type) { - fProjection = new TEveRPhiProjection(fCenter); - break; + case TEveProjection::kPT_RPhi: + { + fProjections[type] = new TEveRPhiProjection(); + break; + } + case TEveProjection::kPT_RhoZ: + { + fProjections[type] = new TEveRhoZProjection(); + break; + } + default: + throw(eH + "projection type not valid."); + break; } - case TEveProjection::kPT_RhoZ: - { - fProjection = new TEveRhoZProjection(fCenter); - break; - } - default: - throw(eH + "projection type not valid."); - break; } - fProjection->SetDistortion(distort); + fProjection = fProjections[type]; + fProjection->SetCenter(fCenter); UpdateName(); } diff --git a/graf3d/eve/src/TEveProjectionManagerEditor.cxx b/graf3d/eve/src/TEveProjectionManagerEditor.cxx index 92ea7c4b48a2c7cb10f04e0ffd431b35b7a05f96..588974e294579ff65a303e818de36192350a4757 100644 --- a/graf3d/eve/src/TEveProjectionManagerEditor.cxx +++ b/graf3d/eve/src/TEveProjectionManagerEditor.cxx @@ -17,13 +17,16 @@ #include "TGComboBox.h" #include "TGLabel.h" -//______________________________________________________________________________ +//============================================================================== // TEveProjectionManagerEditor +//============================================================================== + +//______________________________________________________________________________ // // GUI editor for TEveProjectionManager class. // -ClassImp(TEveProjectionManagerEditor) +ClassImp(TEveProjectionManagerEditor); //______________________________________________________________________________ TEveProjectionManagerEditor::TEveProjectionManagerEditor(const TGWindow *p, @@ -185,7 +188,7 @@ void TEveProjectionManagerEditor::DoType(Int_t type) { // Slot for setting of projection type. - fM->SetProjection((TEveProjection::EPType_e)type, 0.001f * fDistortion->GetValue()); + fM->SetProjection((TEveProjection::EPType_e)type); fM->ProjectChildren(); Update(); } diff --git a/graf3d/eve/src/TEveProjections.cxx b/graf3d/eve/src/TEveProjections.cxx index c574c33074478259b66b142fc0eebe82e35a344e..253793a091cec8f70a0df414d79a8bcd224efb8a 100644 --- a/graf3d/eve/src/TEveProjections.cxx +++ b/graf3d/eve/src/TEveProjections.cxx @@ -29,11 +29,12 @@ ClassImp(TEveProjection); Float_t TEveProjection::fgEps = 0.005f; //______________________________________________________________________________ -TEveProjection::TEveProjection(TEveVector& center) : +TEveProjection::TEveProjection() : fType (kPT_Unknown), fGeoMode (kGM_Unknown), fName (0), - fCenter (center.fX, center.fY, center.fZ), + fCenter (), + fUsePreScale (kFALSE), fDistortion (0.0f), fFixR (300), fFixZ (400), fPastFixRFac (0), fPastFixZFac (0), @@ -58,6 +59,98 @@ void TEveProjection::ProjectVector(TEveVector& v) ProjectPoint(v.fX, v.fY, v.fZ); } +//______________________________________________________________________________ +void TEveProjection::PreScalePoint(Float_t& v0, Float_t& v1) +{ + // Pre-scale point (v0, v1) in projected coordinates: + // RhoZ ~ (rho, z) + // RPhi ~ (r, phi), scaling phi doesn't make much sense. + + if (!fPreScales[0].empty()) + { + Bool_t invp = kFALSE; + if (v0 < 0) { + v0 = -v0; + invp = kTRUE; + } + vPreScale_i i = fPreScales[0].begin(); + while (v0 > i->fMax) + ++i; + v0 = i->fOffset + (v0 - i->fMin)*i->fScale; + if (invp) + v0 = -v0; + } + if (!fPreScales[1].empty()) + { + Bool_t invp = kFALSE; + if (v1 < 0) { + v1 = -v1; + invp = kTRUE; + } + vPreScale_i i = fPreScales[1].begin(); + while (v1 > i->fMax) + ++i; + v1 = i->fOffset + (v1 - i->fMin)*i->fScale; + if (invp) + v1 = -v1; + } +} + +//______________________________________________________________________________ +void TEveProjection::AddPreScaleEntry(Int_t coord, Float_t value, Float_t scale) +{ + // Add new scaling range for given coordinate. + // Arguments: + // coord 0 ~ x, 1 ~ y; + // value value of input coordinate from which to apply this scale; + // scale the scale to apply from value onwards. + // + // NOTE: If pre-scaling is combined with center-displaced then + // the scale of the central region should be 1. This limitation + // can be removed but will cost CPU. + + static const TEveException eh("TEveProjection::AddPreScaleEntry "); + + if (coord < 0 || coord > 1) + throw (eh + "coordinate out of range."); + + const Float_t infty = std::numeric_limits<Float_t>::infinity(); + + vPreScale_t& vec = fPreScales[coord]; + + if (vec.empty()) + { + if (value == 0) + { + vec.push_back(PreScaleEntry_t(0, infty, 0, scale)); + } + else + { + vec.push_back(PreScaleEntry_t(0, value, 0, 1)); + vec.push_back(PreScaleEntry_t(value, infty, value, scale)); + } + } + else + { + PreScaleEntry_t& prev = vec.back(); + if (value <= prev.fMin) + throw (eh + "minimum value not larger than previous one."); + + prev.fMax = value; + Float_t offset = prev.fOffset + (prev.fMax - prev.fMin)*prev.fScale; + vec.push_back(PreScaleEntry_t(value, infty, offset, scale)); + } +} + +//______________________________________________________________________________ +void TEveProjection::ClearPreScales() +{ + // Clear all pre-scaling information. + + fPreScales[0].clear(); + fPreScales[1].clear(); +} + //______________________________________________________________________________ void TEveProjection::UpdateLimit() { @@ -219,8 +312,8 @@ Float_t TEveProjection::GetScreenVal(Int_t i, Float_t x) ClassImp(TEveRhoZProjection); //______________________________________________________________________________ -TEveRhoZProjection::TEveRhoZProjection(TEveVector& center) : - TEveProjection(center) +TEveRhoZProjection::TEveRhoZProjection() : + TEveProjection() { // Constructor. @@ -230,7 +323,7 @@ TEveRhoZProjection::TEveRhoZProjection(TEveVector& center) : //______________________________________________________________________________ void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, - EPProc_e proc ) + EPProc_e proc) { // Project point. @@ -244,6 +337,9 @@ void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, } if (proc == kPP_Distort || proc == kPP_Full) { + if (fUsePreScale) + PreScalePoint(y, x); + // move to center x -= fProjectedCenter.fX; y -= fProjectedCenter.fY; @@ -352,8 +448,8 @@ Bool_t TEveRhoZProjection::AcceptSegment(TEveVector& v1, TEveVector& v2, ClassImp(TEveRPhiProjection); //______________________________________________________________________________ -TEveRPhiProjection::TEveRPhiProjection(TEveVector& center) : - TEveProjection(center) +TEveRPhiProjection::TEveRPhiProjection() : + TEveProjection() { // Constructor. @@ -372,10 +468,20 @@ void TEveRPhiProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, if (proc != kPP_Plane) { - x -= fCenter.fX; - y -= fCenter.fY; - Float_t phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x); - Float_t r = Sqrt(x*x + y*y); + Float_t r, phi; + if (fUsePreScale) + { + r = Sqrt(x*x + y*y); + phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x); + PreScalePoint(r, phi); + x = r*Cos(phi); + y = r*Sin(phi); + } + + x -= fCenter.fX; + y -= fCenter.fY; + r = Sqrt(x*x + y*y); + phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x); if (r > fFixR) r = fFixR + fPastFixRScale*(r - fFixR); diff --git a/tutorials/eve/projection_test_prescale.C b/tutorials/eve/projection_test_prescale.C new file mode 100644 index 0000000000000000000000000000000000000000..0ce2868a244d1976a2c3972db4d1780cdcc7fa49 --- /dev/null +++ b/tutorials/eve/projection_test_prescale.C @@ -0,0 +1,77 @@ +const char* esd_geom_file_name = "http://root.cern.ch/files/alice_ESDgeometry.root"; + +void projection_test_prescale() +{ + TFile::SetCacheFileDir("."); + TEveManager::Create(); + + // camera + TEveScene* s = gEve->SpawnNewScene("Projected Event"); + gEve->GetDefViewer()->AddScene(s); + TGLViewer* v = (TGLViewer *)gEve->GetGLViewer(); + v->SetCurrentCamera(TGLViewer::kCameraOrthoXOY); + TGLOrthoCamera* cam = (TGLOrthoCamera*) v->CurrentCamera(); + cam->SetZoomMinMax(0.2, 20); + + TGLCameraMarkupStyle* mup = v->GetCameraMarkup(); + if (mup) mup->SetShow(kFALSE); + + // projections + TEveProjectionManager* mng = new TEveProjectionManager(); + { + mng->SetProjection(TEveProjection::kPT_RPhi); + TEveProjection* p = mng->GetProjection(); + p->AddPreScaleEntry(0, 0, 4); // r scale 2 from 0 + p->AddPreScaleEntry(0, 45, 1); // r scale 1 from 45 + p->AddPreScaleEntry(0, 310, 0.5); + p->SetUsePreScale(1); + } + { + mng->SetProjection(TEveProjection::kPT_RhoZ); + TEveProjection* p = mng->GetProjection(); + // Increase silicon tracker + p->AddPreScaleEntry(0, 0, 4); // rho scale 4 from 0 + p->AddPreScaleEntry(1, 0, 4); // z scale 4 from 0 + // Normal for TPC + p->AddPreScaleEntry(0, 45, 1); // rho scale 1 from 45 + p->AddPreScaleEntry(1, 110, 1); // z scale 1 from 110 + // Reduce the rest + p->AddPreScaleEntry(0, 310, 0.5); + p->AddPreScaleEntry(1, 250, 0.5); + p->SetUsePreScale(1); + } + mng->SetProjection(TEveProjection::kPT_RPhi); + s->AddElement(mng); + + + TEveProjectionAxes* axes = new TEveProjectionAxes(mng); + axes->SetText("TEveProjections demo"); + axes->SetFontFile("comicbd"); + axes->SetFontSize(20); + s->AddElement(axes); + gEve->AddToListTree(axes, kTRUE); + gEve->AddToListTree(mng, kTRUE); + + // Simple geometry + TFile* geom = TFile::Open(esd_geom_file_name, "CACHEREAD"); + if (!geom) + return; + + TEveGeoShapeExtract* gse = (TEveGeoShapeExtract*) geom->Get("Gentle"); + TEveGeoShape* gsre = TEveGeoShape::ImportShapeExtract(gse, 0); + geom->Close(); + delete geom; + gEve->AddGlobalElement(gsre); + gEve->GetGlobalScene()->SetRnrState(kFALSE); + mng->ImportElements(gsre); + + TEveLine* line = new TEveLine; + line->SetMainColor(kGreen); + for (Int_t i=0; i<160; ++i) + line->SetNextPoint(120*sin(0.2*i), 120*cos(0.2*i), 80-i); + gEve->AddElement(line); + mng->ImportElements(line); + line->SetRnrSelf(kFALSE); + + gEve->Redraw3D(kTRUE); +}