#include "TEveGeoShape.h"
#include "TEveTrans.h"
#include "TEveManager.h"
#include "TEvePolygonSetProjected.h"
#include "TEveProjections.h"
#include "TEveProjectionManager.h"
#include "TEveGeoShapeExtract.h"
#include "TEveGeoPolyShape.h"
#include "TROOT.h"
#include "TBuffer3D.h"
#include "TVirtualViewer3D.h"
#include "TColor.h"
#include "TFile.h"
#include "TGeoShape.h"
#include "TGeoVolume.h"
#include "TGeoNode.h"
#include "TGeoShapeAssembly.h"
#include "TGeoCompositeShape.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TVirtualGeoPainter.h"
namespace
{
TGeoManager* init_geo_mangeur()
{
TGeoManager* old = gGeoManager;
gGeoManager = 0;
TGeoManager* mgr = new TGeoManager();
mgr->SetNameTitle("TEveGeoShape::fgGeoMangeur",
"Static geo manager used for wrapped TGeoShapes.");
gGeoManager = old;
return mgr;
}
}
ClassImp(TEveGeoShape);
TGeoManager* TEveGeoShape::fgGeoMangeur = init_geo_mangeur();
TGeoManager* TEveGeoShape::GetGeoMangeur()
{
return fgGeoMangeur;
}
TEveGeoShape::TEveGeoShape(const char* name, const char* title) :
TEveElement (fColor),
TNamed (name, title),
fColor (0),
fNSegments (0),
fShape (0)
{
InitMainTrans();
}
TEveGeoShape::~TEveGeoShape()
{
SetShape(0);
}
void TEveGeoShape::SetShape(TGeoShape* s)
{
TEveGeoManagerHolder gmgr(fgGeoMangeur);
if (fShape) {
fShape->SetUniqueID(fShape->GetUniqueID() - 1);
if (fShape->GetUniqueID() == 0)
delete fShape;
}
fShape = s;
if (fShape) {
fShape->SetUniqueID(fShape->GetUniqueID() + 1);
}
}
void TEveGeoShape::Paint(Option_t* )
{
static const TEveException eh("TEveGeoShape::Paint ");
if (fShape == 0)
return;
TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);
TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D
(TBuffer3D::kCore, kFALSE);
buff.fID = this;
buff.fColor = GetMainColor();
buff.fTransparency = GetMainTransparency();
RefMainTrans().SetBuffer3D(buff);
buff.fLocalFrame = kTRUE;
Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
if (fNSegments > 2)
sections |= TBuffer3D::kRawSizes | TBuffer3D::kRaw;
fShape->GetBuffer3D(sections, kTRUE);
Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);
if (reqSec != TBuffer3D::kNone) {
if (reqSec & TBuffer3D::kCore)
Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
fShape->GetBuffer3D(reqSec, kTRUE);
reqSec = gPad->GetViewer3D()->AddObject(buff);
}
if (reqSec != TBuffer3D::kNone)
Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
}
void TEveGeoShape::Save(const char* file, const char* name)
{
Warning("Save()", "This function is deprecated, use SaveExtract() instead.");
SaveExtract(file, name);
}
void TEveGeoShape::SaveExtract(const char* file, const char* name)
{
TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);
TFile f(file, "RECREATE");
gse->Write(name);
f.Close();
}
void TEveGeoShape::WriteExtract(const char* name)
{
TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);
gse->Write(name);
}
TEveGeoShapeExtract* TEveGeoShape::DumpShapeTree(TEveGeoShape* gsre,
TEveGeoShapeExtract* parent)
{
TEveGeoShapeExtract* she = new TEveGeoShapeExtract(gsre->GetName(), gsre->GetTitle());
she->SetTrans(gsre->RefMainTrans().Array());
Int_t ci = gsre->GetColor();
TColor* c = gROOT->GetColor(ci);
Float_t rgba[4] = {1, 0, 0, 1 - gsre->GetMainTransparency()/100.};
if (c)
{
rgba[0] = c->GetRed();
rgba[1] = c->GetGreen();
rgba[2] = c->GetBlue();
}
she->SetRGBA(rgba);
she->SetRnrSelf(gsre->GetRnrSelf());
she->SetRnrElements(gsre->GetRnrChildren());
she->SetShape(gsre->GetShape());
if (gsre->HasChildren())
{
TList* ele = new TList();
she->SetElements(ele);
she->GetElements()->SetOwner(true);
TEveElement::List_i i = gsre->BeginChildren();
while (i != gsre->EndChildren()) {
TEveGeoShape* l = dynamic_cast<TEveGeoShape*>(*i);
DumpShapeTree(l, she);
i++;
}
}
if (parent)
parent->GetElements()->Add(she);
return she;
}
TEveGeoShape* TEveGeoShape::ImportShapeExtract(TEveGeoShapeExtract* gse,
TEveElement* parent)
{
TEveGeoManagerHolder gmgr(fgGeoMangeur);
TEveManager::TRedrawDisabler redrawOff(gEve);
TEveGeoShape* gsre = SubImportShapeExtract(gse, parent);
gsre->ElementChanged();
return gsre;
}
TEveGeoShape* TEveGeoShape::SubImportShapeExtract(TEveGeoShapeExtract* gse,
TEveElement* parent)
{
TEveGeoShape* gsre = new TEveGeoShape(gse->GetName(), gse->GetTitle());
gsre->RefMainTrans().SetFromArray(gse->GetTrans());
const Float_t* rgba = gse->GetRGBA();
gsre->SetMainColorRGB(rgba[0], rgba[1], rgba[2]);
gsre->SetMainAlpha(rgba[3]);
gsre->SetRnrSelf(gse->GetRnrSelf());
gsre->SetRnrChildren(gse->GetRnrElements());
gsre->SetShape(gse->GetShape());
if (parent)
parent->AddElement(gsre);
if (gse->HasElements())
{
TIter next(gse->GetElements());
TEveGeoShapeExtract* chld;
while ((chld = (TEveGeoShapeExtract*) next()) != 0)
SubImportShapeExtract(chld, gsre);
}
return gsre;
}
TClass* TEveGeoShape::ProjectedClass(const TEveProjection* p) const
{
if (p->Is2D())
return TEvePolygonSetProjected::Class();
else
return TEveGeoShapeProjected::Class();
}
TBuffer3D* TEveGeoShape::MakeBuffer3D()
{
if (fShape == 0) return 0;
if (dynamic_cast<TGeoShapeAssembly*>(fShape)) {
return 0;
}
TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);
TBuffer3D* buff = fShape->MakeBuffer3D();
TEveTrans& mx = RefMainTrans();
if (mx.GetUseTrans())
{
Int_t n = buff->NbPnts();
Double_t* pnts = buff->fPnts;
for(Int_t k = 0; k < n; ++k)
{
mx.MultiplyIP(&pnts[3*k]);
}
}
return buff;
}
ClassImp(TEveGeoShapeProjected);
TEveGeoShapeProjected::TEveGeoShapeProjected() :
TEveElementList("TEveGeoShapeProjected", "", kTRUE),
fBuff(0)
{
}
void TEveGeoShapeProjected::SetDepthLocal(Float_t )
{
Warning("SetDepthLocal", "This function only exists to fulfill an abstract interface.");
}
void TEveGeoShapeProjected::SetProjection(TEveProjectionManager* mng,
TEveProjectable* model)
{
TEveProjected::SetProjection(mng, model);
TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(fProjectable);
SetMainColor(gre->GetMainColor());
SetMainTransparency(gre->GetMainTransparency());
}
void TEveGeoShapeProjected::UpdateProjection()
{
TEveGeoShape *gre = dynamic_cast<TEveGeoShape*>(fProjectable);
TEveProjection *prj = fManager->GetProjection();
delete fBuff;
fBuff = gre->MakeBuffer3D();
if (fBuff)
{
fBuff->SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kRawSizes | TBuffer3D::kRaw);
Double_t *p = fBuff->fPnts;
for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
{
prj->ProjectPointdv(p, 0);
}
}
ResetBBox();
}
void TEveGeoShapeProjected::ComputeBBox()
{
if (fBuff && fBuff->NbPnts() > 0)
{
BBoxInit();
Double_t *p = fBuff->fPnts;
for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
{
BBoxCheckPoint(p[0], p[1], p[2]);
}
}
else
{
BBoxZero();
}
}
void TEveGeoShapeProjected::Paint(Option_t* )
{
static const TEveException eh("TEveGeoShapeProjected::Paint ");
if (fBuff == 0)
return;
TBuffer3D &buff = *fBuff;
buff.fID = this;
buff.fColor = GetMainColor();
buff.fTransparency = GetMainTransparency();
buff.fLocalFrame = kTRUE;
Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);
if (reqSec != TBuffer3D::kNone)
Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
}