Belle II Software development
VisualRepMap.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <display/VisualRepMap.h>
10
11#include <display/EveTower.h>
12#include <framework/logging/Logger.h>
13#include <framework/datastore/RelationVector.h>
14#include <framework/datastore/DataStore.h>
15
16#include <TEveSelection.h>
17#include <TEveCaloData.h>
18#include <TEveManager.h>
19
20#include <boost/bimap/bimap.hpp>
21#include <boost/bimap/unordered_multiset_of.hpp>
22
23using namespace Belle2;
24
25namespace {
27 typedef boost::bimaps::bimap <
28 boost::bimaps::unordered_multiset_of<const TObject*>,
29 boost::bimaps::unordered_multiset_of<TEveElement*>
30 > DataStoreEveElementMap_Base;
31}
32
34class VisualRepMap::DataStoreEveElementMap : public DataStoreEveElementMap_Base { };
35
37{
38 static VisualRepMap instance;
39 return &instance;
40}
41
43
45
47{
49
50 for (EveTower* t : m_eclTowers)
51 delete t;
52 m_eclTowers.clear();
53}
54
55
56const TObject* VisualRepMap::getDataStoreObject(TEveElement* elem) const
57{
58 //special handling for TEveCaloData
59 if (TEveCaloData* caloData = dynamic_cast<TEveCaloData*>(elem)) {
60 const auto& selectedCells = caloData->GetCellsSelected();
61 if (selectedCells.empty())
62 return nullptr;
63 int id = selectedCells[0].fTower;
64 for (EveTower* eveTower : m_eclTowers) {
65 if (eveTower->getID() == id) {
66 elem = eveTower;
67 break;
68 }
69 }
70 }
71
72 const auto& it = m_dataStoreEveElementMap->right.find(elem);
73 if (it != m_dataStoreEveElementMap->right.end())
74 return it->second;
75 return nullptr;
76}
77
78TEveElement* VisualRepMap::getEveElement(const TObject* obj) const
79{
80 const auto& it = m_dataStoreEveElementMap->left.find(obj);
81 if (it != m_dataStoreEveElementMap->left.end())
82 return it->second;
83 return nullptr;
84}
85
86
87void VisualRepMap::select(const TObject* object) const
88{
90 B2FATAL("recursive select() call detected. Please check isCurrentlySelecting().");
92 auto range = m_dataStoreEveElementMap->left.equal_range(object);
93 for (auto it = range.first; it != range.second; ++it) {
94 TEveElement* elem = it->second;
95 if (elem and !gEve->GetSelection()->HasChild(elem)) {
96 //select this object in addition to existing selection
97 gEve->GetSelection()->UserPickedElement(elem, true);
98 }
99 }
100 m_currentlySelecting = false;
101}
102
103void VisualRepMap::selectOnly(const TEveElement* eveObj)
104{
105 //copy current selection, then deselect each element
106 const std::list<TEveElement*> sel(gEve->GetSelection()->BeginChildren(), gEve->GetSelection()->EndChildren());
107 for (TEveElement* el : sel) {
108 if (el == eveObj or el->IsA() == EveTower::Class())
109 continue;
110 gEve->GetSelection()->UserUnPickedElement(el);
111 }
112}
113
114void VisualRepMap::selectRelated(TEveElement* eveObj) const
115{
116 const TObject* representedObject = getDataStoreObject(eveObj);
117 if (representedObject) {
118 //representedObject->Dump();
119
120 const RelationVector<TObject>& relatedObjects = DataStore::getRelationsWithObj<TObject>(representedObject, "ALL");
121 for (const TObject& relObj : relatedObjects) {
122 select(&relObj);
123 }
124 }
125}
126
128{
129 if (!gEve)
130 return;
131 //equivalent to clicking into empty space
132 gEve->GetSelection()->UserPickedElement(nullptr);
133}
134
135void VisualRepMap::add(const TObject* dataStoreObject, TEveElement* visualRepresentation)
136{
137 if (!dataStoreObject) {
138 B2ERROR("Trying to insert NULL for object represented by " << visualRepresentation->GetElementName());
139 return;
140 }
141 auto ret = m_dataStoreEveElementMap->insert(DataStoreEveElementMap::value_type(dataStoreObject, visualRepresentation));
142 if (!ret.second) {
143 B2DEBUG(100, "Failed to insert object represented by " << visualRepresentation->GetElementName() << "! Duplicate?");
144 }
145}
146
147void VisualRepMap::addCluster(const TObject* dataStoreObject, TEveCaloData* caloData, int towerID)
148{
149 EveTower* tower = new EveTower(caloData, towerID);
150 tower->IncDenyDestroy(); //otherwise the selection wants to own this.
151 m_eclTowers.push_back(tower);
152
153 add(dataStoreObject, tower);
154}
static RelationVector< T > getRelationsWithObj(const TObject *object, const std::string &name="", const std::string &namedRelation="")
Get the relations between an object and other objects in a store array.
Definition DataStore.h:412
handles selection of individual ECLClusters (getting them out of TEve is hard).
Definition EveTower.h:20
Class for type safe access to objects that are referred to in relations.
~VisualRepMap()
destructor
void addCluster(const TObject *dataStoreObject, TEveCaloData *caloData, int towerID)
Selection inside TEveCalo* is complicated, use this to keep track of ECL clusters.
const TObject * getDataStoreObject(TEveElement *elem) const
Get object represented by given visual representation.
bool m_currentlySelecting
are we currently in a select() call?
static VisualRepMap * getInstance()
get instance pointer.
void selectRelated(TEveElement *eveObj) const
Select related objects.
TEveElement * getEveElement(const TObject *obj) const
Get (first) visual representation of given object.
std::vector< EveTower * > m_eclTowers
individual ECL towers (getting them out of TEve is hard).
static void selectOnly(const TEveElement *eveObj)
Deselect all other objects.
void select(const TObject *object) const
Select the representation of the given object.
DataStoreEveElementMap * m_dataStoreEveElementMap
Map DataStore contents in current event with their visual representation.
static void clearSelection()
Clear existing selection in Eve Browser.
void clear()
Remove all contents in map.
VisualRepMap()
default constructor
void add(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
Hide implementation in private class.
Abstract base class for different kinds of events.