ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
graphics
VP1
VP1Base
src
VP1ExtraSepLayerHelper.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
VP1Base/VP1ExtraSepLayerHelper.h
"
6
#include "
VP1Base/VP1Msg.h
"
7
#include <Inventor/C/errors/debugerror.h>
8
#include <Inventor/nodes/SoSeparator.h>
9
#include <Inventor/nodes/SoMaterial.h>
10
#include <map>
11
#include <iostream>
12
13
//____________________________________________________________________
14
class
VP1ExtraSepLayerHelper::Imp
{
15
public
:
16
17
Imp
(SoSeparator*
topsep
,
int
numberOfNodesPerExtraSep
)
18
:
topsep
(
topsep
),
limitpersep
(
numberOfNodesPerExtraSep
),
largechangessave
(0) {}
19
20
SoSeparator *
topsep
;
21
const
int
limitpersep
;
22
std::map<SoNode*,SoSeparator*>
nodes2extrasep
;
//We dont do any special refcounting here.
23
24
//For notifications:
25
int
largechangessave
;
26
27
//For addNodeUnderMaterial:
28
std::map<SoMaterial*,std::pair<SoSeparator*,VP1ExtraSepLayerHelper*> >
mat2sepandhelper
;
29
};
30
31
32
//____________________________________________________________________
33
VP1ExtraSepLayerHelper::VP1ExtraSepLayerHelper
(SoSeparator* topsep,
int
numberOfNodesPerExtraSep
)
34
:
m_d
(new
Imp
(topsep,
numberOfNodesPerExtraSep
))
35
{
36
m_d
->topsep->ref();
37
}
38
39
//____________________________________________________________________
40
VP1ExtraSepLayerHelper::~VP1ExtraSepLayerHelper
()
41
{
42
std::map<SoMaterial*,std::pair<SoSeparator*,VP1ExtraSepLayerHelper*> >
::iterator
it, itE =
m_d
->mat2sepandhelper.end();
43
for
(it =
m_d
->mat2sepandhelper.begin();it!=itE;++it) {
44
delete
it->second.second;
45
it->second.first->unref();
46
}
47
m_d
->topsep->removeAllChildren();
48
m_d
->topsep->unref();
49
delete
m_d
;
m_d
=0;
50
}
51
52
53
//____________________________________________________________________
54
void
VP1ExtraSepLayerHelper::addNode
(SoNode*
node
)
55
{
56
assert(
m_d
->nodes2extrasep.find(
node
)==
m_d
->nodes2extrasep.end());
57
if
(
VP1Msg::verbose
()) {
58
if
(
m_d
->nodes2extrasep.find(
node
)!=
m_d
->nodes2extrasep.end())
59
VP1Msg::message
(
"VP1ExtraSepLayerHelper::addNode ERROR: Node already added!"
);
60
}
61
62
if
(
m_d
->topsep->getNumChildren()==0) {
63
SoSeparator * sep =
new
SoSeparator;
64
if
(
VP1Msg::verbose
())
65
sep->setName(
"SepHelperInternalSep"
);
66
sep->renderCaching.setValue(SoSeparator::ON);
67
sep->boundingBoxCaching.setValue(SoSeparator::ON);
68
sep->addChild(
node
);
69
m_d
->topsep->addChild(sep);
70
m_d
->nodes2extrasep[
node
]=sep;
71
return
;
72
}
73
74
//Try to retrieve the last of the extra separators, and see if it still has room:
75
assert(
m_d
->topsep->getChild(
m_d
->topsep->getNumChildren()-1)->getTypeId().isDerivedFrom(SoSeparator::getClassTypeId()));
76
SoSeparator * lastsep =
static_cast<
SoSeparator*
>
(
m_d
->topsep->getChild(
m_d
->topsep->getNumChildren()-1));
77
if
(lastsep->getNumChildren()<
m_d
->limitpersep) {
78
lastsep->addChild(
node
);
79
m_d
->nodes2extrasep[
node
]=lastsep;
80
return
;
81
}
82
83
//Add a new sep and return.
84
SoSeparator * sep =
new
SoSeparator;
85
if
(
VP1Msg::verbose
())
86
sep->setName(
"SepHelperInternalSep"
);
87
sep->renderCaching.setValue(SoSeparator::ON);
88
sep->boundingBoxCaching.setValue(SoSeparator::ON);
89
sep->addChild(
node
);
90
m_d
->topsep->addChild(sep);
91
m_d
->nodes2extrasep[
node
]=sep;
92
}
93
94
//____________________________________________________________________
95
void
VP1ExtraSepLayerHelper::removeNode
(SoNode*
node
)
96
{
97
assert(
m_d
->nodes2extrasep.find(
node
)!=
m_d
->nodes2extrasep.end());
98
if
(
VP1Msg::verbose
()) {
99
if
(
m_d
->nodes2extrasep.find(
node
)==
m_d
->nodes2extrasep.end())
100
VP1Msg::message
(
"VP1ExtraSepLayerHelper::removeNode ERROR: Node not added previously!"
);
101
}
102
103
//Find extrasep and lastsep:
104
SoSeparator * extrasep =
m_d
->nodes2extrasep[
node
];
105
assert(extrasep->findChild(
node
)>-1);
106
assert(
m_d
->topsep->getChild(
m_d
->topsep->getNumChildren()-1)->getTypeId()==SoSeparator::getClassTypeId());
107
SoSeparator * lastsep =
static_cast<
SoSeparator*
>
(
m_d
->topsep->getChild(
m_d
->topsep->getNumChildren()-1));
108
assert(lastsep->getNumChildren()>0);
109
110
//First, remove the node:
111
node
->ref();
112
extrasep->removeChild(
node
);
113
node
->unref();
114
m_d
->nodes2extrasep.erase(
m_d
->nodes2extrasep.find(
node
));
115
116
//Do we need to move a node from the last separator into the separator?
117
if
(lastsep!=extrasep&&lastsep->getNumChildren()>0) {
118
SoNode * othernode = lastsep->getChild(lastsep->getNumChildren()-1);
119
othernode->ref();
120
lastsep->removeChild(othernode);
121
extrasep->addChild(othernode);
122
othernode->unref();
123
m_d
->nodes2extrasep[othernode] = extrasep;
124
}
125
126
//Do we need to remove the last separator?
127
if
(lastsep->getNumChildren()==0) {
128
lastsep->ref();
129
m_d
->topsep->removeChild(lastsep);
130
lastsep->unref();
131
}
132
}
133
134
//____________________________________________________________________
135
void
VP1ExtraSepLayerHelper::largeChangesBegin
()
136
{
137
++(
m_d
->largechangessave);
138
m_d
->topsep->enableNotify(
false
);
139
//We "sterilise" the extra separators and the extra sep helpers
140
//also.
141
142
//Thus, we disable notifications on all children of topsep, and we
143
//call largeChangesBegin on all internal sephelpers.
144
145
int
n =
m_d
->topsep->getNumChildren();
146
for
(
int
i = 0; i < n; ++i)
147
m_d
->topsep->getChild(i)->enableNotify(
false
);
148
149
std::map<SoMaterial*,std::pair<SoSeparator*,VP1ExtraSepLayerHelper*> >
::iterator
it, itE =
m_d
->mat2sepandhelper.end();
150
for
(it =
m_d
->mat2sepandhelper.begin(); it!=itE;++it)
151
it->second.second->largeChangesBegin();
152
153
}
154
155
//____________________________________________________________________
156
void
VP1ExtraSepLayerHelper::largeChangesEnd
()
157
{
158
if
(
m_d
->largechangessave<=0)
159
return
;
160
if
(--(
m_d
->largechangessave)!=0)
161
return
;
162
163
std::map<SoMaterial*,std::pair<SoSeparator*,VP1ExtraSepLayerHelper*> >
::iterator
it, itE =
m_d
->mat2sepandhelper.end();
164
for
(it =
m_d
->mat2sepandhelper.begin(); it!=itE;++it)
165
it->second.second->largeChangesEnd();
166
167
int
n =
m_d
->topsep->getNumChildren();
168
for
(
int
i = 0; i < n; ++i) {
169
m_d
->topsep->getChild(i)->enableNotify(
true
);
170
m_d
->topsep->getChild(i)->touch();
171
}
172
173
m_d
->topsep->enableNotify(
true
);
174
m_d
->topsep->touch();
175
}
176
177
//____________________________________________________________________
178
SoSeparator *
VP1ExtraSepLayerHelper::topSeparator
()
const
179
{
180
return
m_d
->topsep;
181
}
182
183
//____________________________________________________________________
184
int
VP1ExtraSepLayerHelper::numberOfNodesPerExtraSep
()
const
185
{
186
return
m_d
->limitpersep;
187
}
188
189
//____________________________________________________________________
190
void
VP1ExtraSepLayerHelper::addNodeUnderMaterial
( SoNode *
node
, SoMaterial * mat )
191
{
192
VP1Msg::messageVerbose
(
"VP1ExtraSepLayerHelper::addNodeUnderMaterial()"
);
193
194
std::map<SoMaterial*,std::pair<SoSeparator*,VP1ExtraSepLayerHelper*> >
::iterator
it =
m_d
->mat2sepandhelper.find(mat);
195
if
(it==
m_d
->mat2sepandhelper.end()) {
196
197
SoSeparator * matsep =
new
SoSeparator;
198
if
(
VP1Msg::verbose
())
199
matsep->setName(
"SepHelperInternalSep_MatSep"
);
200
matsep->ref();
201
matsep->addChild(mat);
202
SoSeparator * sep =
new
SoSeparator;
203
if
(
VP1Msg::verbose
())
204
sep->setName(
"SepHelperInternalSep_InternalSepHelperTop"
);
205
matsep->addChild(sep);
206
VP1ExtraSepLayerHelper
* mathelper =
new
VP1ExtraSepLayerHelper
(sep,
m_d
->limitpersep);
207
m_d
->mat2sepandhelper[mat] = std::pair<SoSeparator*,VP1ExtraSepLayerHelper*>(matsep,mathelper);
208
mathelper->
addNode
(
node
);
209
addNode
(matsep);
210
}
else
{
211
it->second.second->addNode(
node
);
212
}
213
}
214
215
//____________________________________________________________________
216
void
VP1ExtraSepLayerHelper::removeNodeUnderMaterial
(SoNode*
node
,SoMaterial*mat)
217
{
218
std::map<SoMaterial*,std::pair<SoSeparator*,VP1ExtraSepLayerHelper*> >
::iterator
it =
m_d
->mat2sepandhelper.find(mat);
219
if
(it==
m_d
->mat2sepandhelper.end())
220
return
;
221
it->second.second->removeNode(
node
);
222
if
(it->second.second->topSeparator()->getNumChildren()==0) {
223
//No more use for this material apparently:
224
removeNode
(it->second.first);
225
it->second.first->unref();
226
m_d
->mat2sepandhelper.erase(it);
227
}
228
}
229
230
//____________________________________________________________________
231
void
VP1ExtraSepLayerHelper::moveNodeToNewMaterial
(SoNode*
node
,SoMaterial* oldmat,SoMaterial* newmat)
232
{
233
addNodeUnderMaterial
(
node
,newmat);
234
removeNodeUnderMaterial
(
node
,oldmat);
235
}
VP1ExtraSepLayerHelper.h
VP1Msg.h
iterator
VP1ExtraSepLayerHelper::Imp
Definition
VP1ExtraSepLayerHelper.cxx:14
VP1ExtraSepLayerHelper::Imp::limitpersep
const int limitpersep
Definition
VP1ExtraSepLayerHelper.cxx:21
VP1ExtraSepLayerHelper::Imp::mat2sepandhelper
std::map< SoMaterial *, std::pair< SoSeparator *, VP1ExtraSepLayerHelper * > > mat2sepandhelper
Definition
VP1ExtraSepLayerHelper.cxx:28
VP1ExtraSepLayerHelper::Imp::Imp
Imp(SoSeparator *topsep, int numberOfNodesPerExtraSep)
Definition
VP1ExtraSepLayerHelper.cxx:17
VP1ExtraSepLayerHelper::Imp::largechangessave
int largechangessave
Definition
VP1ExtraSepLayerHelper.cxx:25
VP1ExtraSepLayerHelper::Imp::topsep
SoSeparator * topsep
Definition
VP1ExtraSepLayerHelper.cxx:20
VP1ExtraSepLayerHelper::Imp::nodes2extrasep
std::map< SoNode *, SoSeparator * > nodes2extrasep
Definition
VP1ExtraSepLayerHelper.cxx:22
VP1ExtraSepLayerHelper::removeNodeUnderMaterial
void removeNodeUnderMaterial(SoNode *, SoMaterial *)
Definition
VP1ExtraSepLayerHelper.cxx:216
VP1ExtraSepLayerHelper::~VP1ExtraSepLayerHelper
~VP1ExtraSepLayerHelper()
Definition
VP1ExtraSepLayerHelper.cxx:40
VP1ExtraSepLayerHelper::largeChangesEnd
void largeChangesEnd()
Definition
VP1ExtraSepLayerHelper.cxx:156
VP1ExtraSepLayerHelper::numberOfNodesPerExtraSep
int numberOfNodesPerExtraSep() const
Definition
VP1ExtraSepLayerHelper.cxx:184
VP1ExtraSepLayerHelper::addNode
void addNode(SoNode *)
Definition
VP1ExtraSepLayerHelper.cxx:54
VP1ExtraSepLayerHelper::m_d
Imp * m_d
Definition
VP1ExtraSepLayerHelper.h:55
VP1ExtraSepLayerHelper::moveNodeToNewMaterial
void moveNodeToNewMaterial(SoNode *, SoMaterial *oldmat, SoMaterial *newmat)
Definition
VP1ExtraSepLayerHelper.cxx:231
VP1ExtraSepLayerHelper::largeChangesBegin
void largeChangesBegin()
Definition
VP1ExtraSepLayerHelper.cxx:135
VP1ExtraSepLayerHelper::removeNode
void removeNode(SoNode *)
Definition
VP1ExtraSepLayerHelper.cxx:95
VP1ExtraSepLayerHelper::VP1ExtraSepLayerHelper
VP1ExtraSepLayerHelper(SoSeparator *topsep, int numberOfNodesPerExtraSep=32)
Definition
VP1ExtraSepLayerHelper.cxx:33
VP1ExtraSepLayerHelper::addNodeUnderMaterial
void addNodeUnderMaterial(SoNode *, SoMaterial *)
Definition
VP1ExtraSepLayerHelper.cxx:190
VP1ExtraSepLayerHelper::topSeparator
SoSeparator * topSeparator() const
Definition
VP1ExtraSepLayerHelper.cxx:178
VP1Msg::messageVerbose
static void messageVerbose(const QString &)
Definition
VP1Msg.cxx:84
VP1Msg::verbose
static bool verbose()
Definition
VP1Msg.h:31
VP1Msg::message
static void message(const QString &, IVP1System *sys=0)
Definition
VP1Msg.cxx:30
node
Definition
node.h:24
Generated on
for ATLAS Offline Software by
1.17.0