23
#include "PreCompiled.h"
26
# include <boost/algorithm/string/predicate.hpp>
27
# include <Inventor/elements/SoCacheElement.h>
28
# include <Inventor/misc/SoState.h>
31
#include "SoFCSelectionContext.h"
32
#include "SoFCUnifiedSelection.h"
39
SoFCSelectionContext::~SoFCSelectionContext() {
44
bool SoFCSelectionContext::checkGlobal(SoFCSelectionContextPtr ctx) {
47
SoFCSelectionRoot::checkSelection(sel,selectionColor,hl,highlightColor);
49
selectionIndex.insert(-1);
51
selectionColor = ctx->selectionColor;
52
selectionIndex = ctx->selectionIndex;
54
selectionIndex.clear();
58
highlightIndex = ctx->highlightIndex;
59
highlightColor = ctx->highlightColor;
65
bool SoFCSelectionContext::removeIndex(int index) {
66
auto it = selectionIndex.find(index);
67
if(it != selectionIndex.end()) {
68
selectionIndex.erase(it);
74
int SoFCSelectionContext::merge(int status, SoFCSelectionContextBasePtr &output,
75
SoFCSelectionContextBasePtr input, SoNode *)
77
auto ctx = std::dynamic_pointer_cast<SoFCSelectionContext>(input);
81
if(ctx->selectionIndex.empty()) {
86
auto ret = std::dynamic_pointer_cast<SoFCSelectionContext>(output);
92
if(ctx->isSelectAll())
95
if(ret->isSelectAll()) {
98
ret = std::dynamic_pointer_cast<SoFCSelectionContext>(ret);
101
ret->selectionIndex = ctx->selectionIndex;
105
std::vector<int> remove;
106
for(auto idx : ret->selectionIndex) {
107
if(!ctx->selectionIndex.count(idx))
108
remove.push_back(idx);
111
for(auto idx : remove) {
114
output = ret->copy();
115
ret = std::dynamic_pointer_cast<SoFCSelectionContext>(ret);
118
ret->selectionIndex.erase(idx);
119
if(ret->selectionIndex.empty())
127
bool SoFCSelectionContextEx::setColors(
128
const std::map<std::string,App::Color> &colors, const std::string &element) {
129
std::map<int,App::Color> tmp;
130
auto it = colors.find("");
132
tmp[-1] = it->second;
133
for(auto it=colors.lower_bound(element);it!=colors.end();++it) {
134
if(!boost::starts_with(it->first,element))
136
if(it->first.size()==element.size())
137
tmp[-1] = it->second;
139
int idx = std::atoi(it->first.c_str()+4);
142
tmp[idx] = it->second;
146
if(tmp == this->colors)
148
this->colors.swap(tmp);
152
uint32_t SoFCSelectionContextEx::packColor(const App::Color &c, bool &hasTransparency) {
153
float trans = std::max(trans0,c.a);
155
hasTransparency = true;
156
return SbColor(c.r,c.g,c.b).getPackedValue(trans);
159
bool SoFCSelectionContextEx::applyColor(int idx, std::vector<uint32_t> &packedColors, bool &hasTransparency) {
162
auto it = colors.find(idx);
163
if(it==colors.end()) {
164
if(colors.begin()->first >= 0)
168
packedColors.push_back(packColor(it->second,hasTransparency));
172
bool SoFCSelectionContextEx::isSingleColor(uint32_t &color, bool &hasTransparency) {
173
if(!colors.empty() && colors.begin()->first<0) {
174
color = packColor(colors.begin()->second,hasTransparency);
175
return colors.size()==1;
180
int SoFCSelectionContextEx::merge(int status, SoFCSelectionContextBasePtr &output,
181
SoFCSelectionContextBasePtr input, SoNode *node)
183
auto ctx = std::dynamic_pointer_cast<SoFCSelectionContextEx>(input);
184
SoFCSelectionRoot* selectionNode = dynamic_cast<SoFCSelectionRoot*>(node);
187
if(selectionNode && selectionNode->hasColorOverride()) {
196
int status_copy = status;
201
status_copy = SoFCSelectionContext::merge(status_copy,output,input,node);
215
status = status_copy;
216
auto ret = std::dynamic_pointer_cast<SoFCSelectionContextEx>(output);
218
for(auto &v : ctx->colors) {
219
if(ret->colors.count(v.first))
223
output = ret->copy();
224
ret = std::dynamic_pointer_cast<SoFCSelectionContextEx>(output);
227
ret->colors.insert(v);
230
if(selectionNode && selectionNode->hasColorOverride()) {
241
SoFCSelectionCounter::SoFCSelectionCounter()
242
: counter(std::make_shared<int>(0))
245
SoFCSelectionCounter::~SoFCSelectionCounter() = default;
248
bool SoFCSelectionCounter::checkRenderCache(SoState *state) {
250
(hasSelection && Selection().hasSelection()) ||
251
(hasPreselection && Selection().hasPreselection()))
253
if(SoFCSelectionRoot::getCacheMode()!=SoSeparator::OFF)
254
SoCacheElement::invalidate(state);
257
if(!Selection().hasPreselection())
258
hasPreselection = false;
259
if(!Selection().hasSelection())
260
hasSelection = false;
264
void SoFCSelectionCounter::checkAction(SoHighlightElementAction *hlaction) {
265
if(hlaction->isHighlighted())
266
hasPreselection = true;
269
void SoFCSelectionCounter::checkAction(SoSelectionElementAction *selaction, SoFCSelectionContextPtr ctx) {
270
switch(selaction->getType()) {
271
case SoSelectionElementAction::None:
273
case SoSelectionElementAction::All:
274
case SoSelectionElementAction::Append:
280
if(selaction->isSecondary()) {
281
if(ctx && !ctx->counter) {
283
ctx->counter = counter;