#include "TEveScene.h"
#include "TEveViewer.h"
#include "TEveManager.h"
#include "TEveTrans.h"
#include "TEvePad.h"
#include "TGLScenePad.h"
#include "TGLLogicalShape.h"
#include "TGLPhysicalShape.h"
#include "TList.h"
#include "TExMap.h"
ClassImp(TEveScene);
TEveScene::TEveScene(const char* n, const char* t) :
TEveElementList(n, t),
fPad (0),
fGLScene(0),
fChanged (kFALSE),
fSmartRefresh (kTRUE),
fHierarchical (kFALSE)
{
fPad = new TEvePad;
fPad->GetListOfPrimitives()->Add(this);
fGLScene = new TGLScenePad(fPad);
fGLScene->SetName(n);
fGLScene->SetAutoDestruct(kFALSE);
fGLScene->SetSmartRefresh(kTRUE);
}
TEveScene::TEveScene(TGLScenePad* gl_scene, const char* n, const char* t) :
TEveElementList(n, t),
fPad (0),
fGLScene(gl_scene),
fChanged (kFALSE),
fSmartRefresh (kTRUE),
fHierarchical (kFALSE)
{
fPad = new TEvePad;
fPad->GetListOfPrimitives()->Add(this);
fGLScene->SetPad(fPad);
fGLScene->SetName(n);
fGLScene->SetAutoDestruct(kFALSE);
fGLScene->SetSmartRefresh(kTRUE);
}
TEveScene::~TEveScene()
{
fDestructing = kStandard;
gEve->GetViewers()->SceneDestructing(this);
gEve->GetScenes()->RemoveElement(this);
delete fGLScene;
delete fPad;
}
void TEveScene::CollectSceneParents(List_t& scenes)
{
scenes.push_back(this);
}
void TEveScene::Repaint(Bool_t dropLogicals)
{
if (dropLogicals) fGLScene->SetSmartRefresh(kFALSE);
fGLScene->PadPaint(fPad);
if (dropLogicals) fGLScene->SetSmartRefresh(kTRUE);
fChanged = kFALSE;
TGLScene::LogicalShapeMap_t& logs = fGLScene->RefLogicalShapes();
TEveElement* elm;
for (TGLScene::LogicalShapeMapIt_t li = logs.begin(); li != logs.end(); ++li)
{
elm = dynamic_cast<TEveElement*>(li->first);
if (elm && li->second->Ref() == 1)
{
TGLPhysicalShape* pshp = const_cast<TGLPhysicalShape*>(li->second->GetFirstPhysical());
pshp->Select(elm->GetSelectedLevel());
}
}
if (fHierarchical)
{
RetransHierarchically();
}
}
void TEveScene::RetransHierarchically()
{
fGLScene->BeginUpdate();
RetransHierarchicallyRecurse(this, RefMainTrans());
fGLScene->EndUpdate();
}
void TEveScene::RetransHierarchicallyRecurse(TEveElement* el, const TEveTrans& tp)
{
static const TEveException eh("TEveScene::RetransHierarchicallyRecurse ");
TEveTrans t(tp);
if (el->HasMainTrans())
t *= el->RefMainTrans();
if (el->GetRnrSelf() && el != this)
{
fGLScene->UpdatePhysioLogical(el->GetRenderObject(eh), t.Array(), 0);
}
if (el->GetRnrChildren())
{
for (List_i i = el->BeginChildren(); i != el->EndChildren(); ++i)
{
if ((*i)->GetRnrAnything())
RetransHierarchicallyRecurse(*i, t);
}
}
}
void TEveScene::SetName(const char* n)
{
TEveElementList::SetName(n);
fGLScene->SetName(n);
}
void TEveScene::Paint(Option_t* option)
{
if (GetRnrState())
{
for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
(*i)->PadPaint(option);
}
}
void TEveScene::DestroyElementRenderers(TEveElement* element)
{
static const TEveException eh("TEveScene::DestroyElementRenderers ");
fGLScene->BeginUpdate();
Bool_t changed = fGLScene->DestroyLogical(element->GetRenderObject(eh), kFALSE);
fGLScene->EndUpdate(changed, changed);
}
void TEveScene::DestroyElementRenderers(TObject* rnrObj)
{
fGLScene->BeginUpdate();
Bool_t changed = fGLScene->DestroyLogical(rnrObj, kFALSE);
fGLScene->EndUpdate(changed, changed);
}
const TGPicture* TEveScene::GetListTreeIcon(Bool_t)
{
return TEveElement::fgListTreeIcons[2];
}
ClassImp(TEveSceneList);
TEveSceneList::TEveSceneList(const char* n, const char* t) :
TEveElementList(n, t)
{
SetChildClass(TEveScene::Class());
}
void TEveSceneList::DestroyScenes()
{
List_i i = fChildren.begin();
while (i != fChildren.end())
{
TEveScene* s = (TEveScene*) *(i++);
s->DestroyElements();
s->DestroyOrWarn();
}
}
void TEveSceneList::RepaintChangedScenes(Bool_t dropLogicals)
{
for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
{
TEveScene* s = (TEveScene*) *i;
if (s->IsChanged())
{
s->Repaint(dropLogicals);
}
}
}
void TEveSceneList::RepaintAllScenes(Bool_t dropLogicals)
{
for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
{
((TEveScene*) *i)->Repaint(dropLogicals);
}
}
void TEveSceneList::DestroyElementRenderers(TEveElement* element)
{
static const TEveException eh("TEveSceneList::DestroyElementRenderers ");
TObject* obj = element->GetRenderObject(eh);
for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
{
((TEveScene*)*i)->DestroyElementRenderers(obj);
}
}
void TEveSceneList::ProcessSceneChanges(Bool_t dropLogicals, TExMap* stampMap)
{
static const TEveException eh("TEveSceneList::ProcessSceneChanges ");
typedef std::map<TObject*, TEveElement*> mObjectElement_t;
typedef mObjectElement_t::iterator mObjectElement_i;
mObjectElement_t changed_objects;
{
Long64_t key, value;
TExMapIter stamped_elements(stampMap);
while (stamped_elements.Next(key, value))
{
TEveElement *el = reinterpret_cast<TEveElement*>(key);
changed_objects.insert(std::make_pair(el->GetRenderObject(eh), el));
}
}
for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
{
TEveScene* s = (TEveScene*) *i;
if (s->IsChanged())
{
s->Repaint(dropLogicals);
}
else
{
Bool_t updateViewers = kFALSE;
Bool_t incTimeStamp = kFALSE;
Bool_t transbboxChg = kFALSE;
s->GetGLScene()->BeginUpdate();
TGLScene::LogicalShapeMap_t &logs = s->GetGLScene()->RefLogicalShapes();
TGLScene::LogicalShapeMapIt_t li = logs.begin();
mObjectElement_i ei = changed_objects.begin();
while (li != logs.end() && ei != changed_objects.end())
{
if (li->first == ei->first)
{
if (li->second->Ref() != 1)
Warning("TEveSceneList::ProcessSceneChanges",
"Expect one physical, cnt=%u.", li->second->Ref());
TGLLogicalShape *lshp = li->second;
TGLPhysicalShape *pshp = const_cast<TGLPhysicalShape*>(lshp->GetFirstPhysical());
TEveElement *el = ei->second;
UChar_t bits = el->GetChangeBits();
if (bits & kCBColorSelection)
{
pshp->Select(el->GetSelectedLevel());
pshp->SetDiffuseColor(el->GetMainColor(),
el->GetMainTransparency());
}
if (bits & kCBTransBBox)
{
if (el->HasMainTrans())
pshp->SetTransform(el->PtrMainTrans()->Array());
lshp->UpdateBoundingBox();
incTimeStamp = kTRUE;
transbboxChg = kTRUE;
}
if (bits & kCBObjProps)
{
lshp->DLCacheClear();
}
++li; ++ei;
updateViewers = kTRUE;
}
else if (li->first < ei->first)
{
++li;
}
else
{
++ei;
}
}
s->GetGLScene()->EndUpdate(updateViewers, incTimeStamp, updateViewers);
if (s->GetHierarchical() && transbboxChg)
{
s->RetransHierarchically();
}
}
}
}