Do not use a view provider's bounding box node when handling BoundBox selection style because it leads to some inconsistent behaviour.
Instead let SoBoxSelectionRenderAction render the bounding box.
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
|
||||
#include "SoFCSelectionAction.h"
|
||||
#include "SoFCSelection.h"
|
||||
#include "SoFCUnifiedSelection.h"
|
||||
#include <Inventor/bundles/SoMaterialBundle.h>
|
||||
#include <Inventor/elements/SoSwitchElement.h>
|
||||
#include "Selection.h"
|
||||
@@ -1235,6 +1236,20 @@ SoBoxSelectionRenderAction::apply(SoNode * node)
|
||||
}
|
||||
}
|
||||
PRIVATE(this)->searchaction->reset();
|
||||
|
||||
// Search for selections of SoFCUnifiedSelection
|
||||
PRIVATE(this)->searchaction->setType(SoFCUnifiedSelection::getClassTypeId());
|
||||
PRIVATE(this)->searchaction->setInterest(SoSearchAction::FIRST);
|
||||
PRIVATE(this)->searchaction->apply(node);
|
||||
SoFullPath * path = static_cast<SoFullPath *>(PRIVATE(this)->searchaction->getPath());
|
||||
if (path) {
|
||||
SoFCUnifiedSelection * selection = static_cast<SoFCUnifiedSelection *>(path->getTail());
|
||||
if (selection->getNumSelected()) {
|
||||
PRIVATE(this)->basecolor->rgb.setValue(selection->colorSelection.getValue());
|
||||
this->drawBoxes(path, selection->getList());
|
||||
}
|
||||
}
|
||||
PRIVATE(this)->searchaction->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,6 +197,101 @@ void SoFCUnifiedSelection::write(SoWriteAction * action)
|
||||
}
|
||||
}
|
||||
|
||||
int SoFCUnifiedSelection::getNumSelected(void) const
|
||||
{
|
||||
return this->selectionList.getLength();
|
||||
}
|
||||
|
||||
const SoPathList* SoFCUnifiedSelection::getList(void) const
|
||||
{
|
||||
return &this->selectionList;
|
||||
}
|
||||
|
||||
void SoFCUnifiedSelection::addPath(SoPath * path)
|
||||
{
|
||||
this->selectionList.append(path);
|
||||
}
|
||||
|
||||
void SoFCUnifiedSelection::removePath(const int which)
|
||||
{
|
||||
SoPath * path = this->selectionList[which];
|
||||
path->ref();
|
||||
this->selectionList.remove(which);
|
||||
path->unref();
|
||||
}
|
||||
|
||||
SoPath * SoFCUnifiedSelection::copyFromThis(const SoPath * path) const
|
||||
{
|
||||
SoPath * newpath = NULL;
|
||||
path->ref();
|
||||
int i = path->findNode(this);
|
||||
if (i >= 0) {
|
||||
newpath = path->copy(i);
|
||||
}
|
||||
path->unrefNoDelete();
|
||||
return newpath;
|
||||
}
|
||||
|
||||
int SoFCUnifiedSelection::findPath(const SoPath * path) const
|
||||
{
|
||||
int idx = -1;
|
||||
|
||||
// make copy only if necessary
|
||||
if (path->getHead() != this) {
|
||||
SoPath * newpath = this->copyFromThis(path);
|
||||
if (newpath) {
|
||||
newpath->ref();
|
||||
idx = this->selectionList.findPath(*newpath);
|
||||
newpath->unref();
|
||||
}
|
||||
else {
|
||||
idx = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx = this->selectionList.findPath(*path);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
SoPath * SoFCUnifiedSelection::searchNode(SoNode * node) const
|
||||
{
|
||||
SoSearchAction sa;
|
||||
sa.setNode(node);
|
||||
sa.apply(const_cast<SoFCUnifiedSelection*>(this));
|
||||
SoPath * path = sa.getPath();
|
||||
if (path)
|
||||
path->ref();
|
||||
return path;
|
||||
}
|
||||
|
||||
void SoFCUnifiedSelection::select(SoNode * node)
|
||||
{
|
||||
SoPath * path = this->searchNode(node);
|
||||
if (path) {
|
||||
// don't ref() the path. searchNode() will ref it before returning
|
||||
if (this->findPath(path) < 0)
|
||||
this->addPath(path);
|
||||
path->unref();
|
||||
}
|
||||
}
|
||||
|
||||
void SoFCUnifiedSelection::deselect(const SoPath * path)
|
||||
{
|
||||
int idx = this->findPath(path);
|
||||
if (idx >= 0) this->removePath(idx);
|
||||
}
|
||||
|
||||
void SoFCUnifiedSelection::deselect(SoNode * node)
|
||||
{
|
||||
SoPath * path = this->searchNode(node);
|
||||
if (path) {
|
||||
// don't ref() the path. searchNode() will ref it before returning
|
||||
this->deselect(path);
|
||||
path->unref();
|
||||
}
|
||||
}
|
||||
|
||||
int SoFCUnifiedSelection::getPriority(const SoPickedPoint* p)
|
||||
{
|
||||
const SoDetail* detail = p->getDetail();
|
||||
@@ -306,7 +401,7 @@ void SoFCUnifiedSelection::doAction(SoAction *action)
|
||||
type = SoSelectionElementAction::None;
|
||||
}
|
||||
|
||||
if(checkSelectionStyle(type,vp)) {
|
||||
if (checkSelectionStyle(type,vp)) {
|
||||
SoSelectionElementAction action(type);
|
||||
action.setColor(this->colorSelection.getValue());
|
||||
action.setElement(detail);
|
||||
@@ -328,7 +423,7 @@ void SoFCUnifiedSelection::doAction(SoAction *action)
|
||||
type = SoSelectionElementAction::All;
|
||||
else
|
||||
type = SoSelectionElementAction::None;
|
||||
if(checkSelectionStyle(type,vpd)) {
|
||||
if (checkSelectionStyle(type, vpd)) {
|
||||
SoSelectionElementAction action(type);
|
||||
action.setColor(this->colorSelection.getValue());
|
||||
action.apply(vpd->getRoot());
|
||||
@@ -553,7 +648,7 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action)
|
||||
}
|
||||
|
||||
action->setHandled();
|
||||
if (currenthighlight && checkSelectionStyle(type,vpd)) {
|
||||
if (currenthighlight && checkSelectionStyle(type, vpd)) {
|
||||
SoSelectionElementAction action(type);
|
||||
action.setColor(this->colorSelection.getValue());
|
||||
action.setElement(pp ? pp->getDetail() : 0);
|
||||
@@ -576,15 +671,27 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action)
|
||||
inherited::handleEvent(action);
|
||||
}
|
||||
|
||||
bool SoFCUnifiedSelection::checkSelectionStyle(int type, ViewProvider *vp) {
|
||||
if((type == SoSelectionElementAction::All ||
|
||||
type == SoSelectionElementAction::None) &&
|
||||
bool SoFCUnifiedSelection::checkSelectionStyle(int type, ViewProvider *vp)
|
||||
{
|
||||
if ((type == SoSelectionElementAction::All || type == SoSelectionElementAction::None) &&
|
||||
vp->isDerivedFrom(ViewProviderGeometryObject::getClassTypeId()) &&
|
||||
static_cast<ViewProviderGeometryObject*>(vp)->SelectionStyle.getValue()==1)
|
||||
static_cast<ViewProviderGeometryObject*>(vp)->SelectionStyle.getValue() == 1)
|
||||
{
|
||||
bool selected = type==SoSelectionElementAction::All;
|
||||
static_cast<ViewProviderGeometryObject*>(vp)->showBoundingBox(selected);
|
||||
if(selected) return false;
|
||||
bool selected = (type == SoSelectionElementAction::All);
|
||||
int numSelected = getNumSelected();
|
||||
if (selected) {
|
||||
select(vp->getRoot());
|
||||
}
|
||||
else {
|
||||
deselect(vp->getRoot());
|
||||
}
|
||||
|
||||
if (numSelected != getNumSelected())
|
||||
this->touch();
|
||||
|
||||
if (selected) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <Inventor/fields/SoSFEnum.h>
|
||||
#include <Inventor/fields/SoSFString.h>
|
||||
#include <Inventor/nodes/SoLightModel.h>
|
||||
#include <Inventor/lists/SoPathList.h>
|
||||
#include "View3DInventorViewer.h"
|
||||
#include <list>
|
||||
|
||||
@@ -66,6 +67,8 @@ public:
|
||||
|
||||
const char* getFileFormatName(void) const;
|
||||
void write(SoWriteAction * action);
|
||||
int getNumSelected(void) const;
|
||||
const SoPathList* getList(void) const;
|
||||
|
||||
SoSFColor colorHighlight;
|
||||
SoSFColor colorSelection;
|
||||
@@ -84,11 +87,27 @@ public:
|
||||
bool checkSelectionStyle(int type, ViewProvider *vp);
|
||||
|
||||
friend class View3DInventorViewer;
|
||||
|
||||
protected:
|
||||
virtual ~SoFCUnifiedSelection();
|
||||
//virtual void redrawHighlighted(SoAction * act, SbBool flag);
|
||||
//virtual SbBool readInstance(SoInput * in, unsigned short flags);
|
||||
|
||||
/** @name Nodes selection.
|
||||
* The SoBoxSelectionRenderAction uses these nodes to draw a
|
||||
* bounding box.
|
||||
*/
|
||||
//@{
|
||||
void addPath(SoPath * path);
|
||||
void removePath(const int which);
|
||||
SoPath * copyFromThis(const SoPath * path) const;
|
||||
SoPath * searchNode(SoNode * node) const;
|
||||
int findPath(const SoPath * path) const;
|
||||
void select(SoNode * node);
|
||||
void deselect(const SoPath * path);
|
||||
void deselect(SoNode * node);
|
||||
//@}
|
||||
|
||||
private:
|
||||
//static void turnoffcurrent(SoAction * action);
|
||||
//void setOverride(SoGLRenderAction * action);
|
||||
@@ -99,6 +118,7 @@ private:
|
||||
Gui::Document *pcDocument;
|
||||
|
||||
static SoFullPath * currenthighlight;
|
||||
SoPathList selectionList;
|
||||
|
||||
SbBool highlighted;
|
||||
SbBool setPreSelection;
|
||||
|
||||
@@ -74,13 +74,15 @@ PROPERTY_SOURCE(Gui::ViewProviderGeometryObject, Gui::ViewProviderDragger)
|
||||
|
||||
const App::PropertyIntegerConstraint::Constraints intPercent = {0,100,1};
|
||||
|
||||
ViewProviderGeometryObject::ViewProviderGeometryObject() : pcBoundSwitch(0),pcBoundColor(0)
|
||||
ViewProviderGeometryObject::ViewProviderGeometryObject()
|
||||
: pcBoundSwitch(0)
|
||||
, pcBoundColor(0)
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
bool randomColor = hGrp->GetBool("RandomColor", false);
|
||||
float r,g,b;
|
||||
|
||||
if(randomColor){
|
||||
if (randomColor){
|
||||
float fMax = (float)RAND_MAX;
|
||||
r = (float)rand()/fMax;
|
||||
g = (float)rand()/fMax;
|
||||
@@ -115,6 +117,10 @@ ViewProviderGeometryObject::ViewProviderGeometryObject() : pcBoundSwitch(0),pcBo
|
||||
|
||||
pcBoundingBox = new Gui::SoFCBoundingBox;
|
||||
pcBoundingBox->ref();
|
||||
|
||||
pcBoundColor = new SoBaseColor();
|
||||
pcBoundColor->ref();
|
||||
|
||||
sPixmap = "Feature";
|
||||
}
|
||||
|
||||
@@ -122,6 +128,7 @@ ViewProviderGeometryObject::~ViewProviderGeometryObject()
|
||||
{
|
||||
pcShapeMaterial->unref();
|
||||
pcBoundingBox->unref();
|
||||
pcBoundColor->unref();
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::onChanged(const App::Property* prop)
|
||||
@@ -163,10 +170,8 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
|
||||
pcShapeMaterial->shininess.setValue(Mat.shininess);
|
||||
pcShapeMaterial->transparency.setValue(Mat.transparency);
|
||||
}
|
||||
else if (prop == &BoundingBox || prop == &SelectionStyle) {
|
||||
applyBoundColor();
|
||||
if(SelectionStyle.getValue()==0 || !Selectable.getValue())
|
||||
showBoundingBox( BoundingBox.getValue() );
|
||||
else if (prop == &BoundingBox) {
|
||||
showBoundingBox(BoundingBox.getValue());
|
||||
}
|
||||
|
||||
ViewProviderDragger::onChanged(prop);
|
||||
@@ -230,35 +235,28 @@ SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, co
|
||||
return (pick ? new SoPickedPoint(*pick) : 0);
|
||||
}
|
||||
|
||||
unsigned long ViewProviderGeometryObject::getBoundColor() const {
|
||||
unsigned long ViewProviderGeometryObject::getBoundColor() const
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
if(SelectionStyle.getValue() == 0 || !Selectable.getValue() || !hGrp->GetBool("EnableSelection", true))
|
||||
return hGrp->GetUnsigned("BoundingBoxColor",4294967295UL); // white (255,255,255)
|
||||
else
|
||||
return hGrp->GetUnsigned("SelectionColor",0x00CD00UL); // rgb(0,205,0)
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::applyBoundColor() {
|
||||
if(!pcBoundColor) return;
|
||||
|
||||
unsigned long bbcol = getBoundColor();
|
||||
float r,g,b;
|
||||
r = ((bbcol >> 24) & 0xff) / 255.0; g = ((bbcol >> 16) & 0xff) / 255.0; b = ((bbcol >> 8) & 0xff) / 255.0;
|
||||
pcBoundColor->rgb.setValue(r, g, b);
|
||||
unsigned long bbcol = hGrp->GetUnsigned("BoundingBoxColor",4294967295UL); // white (255,255,255)
|
||||
return bbcol;
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::showBoundingBox(bool show)
|
||||
{
|
||||
if (!pcBoundSwitch && show) {
|
||||
unsigned long bbcol = getBoundColor();
|
||||
float r,g,b;
|
||||
r = ((bbcol >> 24) & 0xff) / 255.0; g = ((bbcol >> 16) & 0xff) / 255.0; b = ((bbcol >> 8) & 0xff) / 255.0;
|
||||
|
||||
pcBoundSwitch = new SoSwitch();
|
||||
SoSeparator* pBoundingSep = new SoSeparator();
|
||||
SoDrawStyle* lineStyle = new SoDrawStyle;
|
||||
lineStyle->lineWidth = 2.0f;
|
||||
pBoundingSep->addChild(lineStyle);
|
||||
|
||||
pcBoundColor = new SoBaseColor();
|
||||
pcBoundColor->rgb.setValue(r, g, b);
|
||||
pBoundingSep->addChild(pcBoundColor);
|
||||
applyBoundColor();
|
||||
|
||||
pBoundingSep->addChild(new SoResetTransform());
|
||||
pBoundingSep->addChild(pcBoundingBox);
|
||||
@@ -267,7 +265,7 @@ void ViewProviderGeometryObject::showBoundingBox(bool show)
|
||||
|
||||
// add to the highlight node
|
||||
pcBoundSwitch->addChild(pBoundingSep);
|
||||
pcRoot->insertChild(pcBoundSwitch,pcRoot->findChild(pcModeSwitch));
|
||||
pcRoot->addChild(pcBoundSwitch);
|
||||
}
|
||||
|
||||
if (pcBoundSwitch) {
|
||||
@@ -277,12 +275,6 @@ void ViewProviderGeometryObject::showBoundingBox(bool show)
|
||||
|
||||
void ViewProviderGeometryObject::setSelectable(bool selectable)
|
||||
{
|
||||
if(SelectionStyle.getValue()) {
|
||||
applyBoundColor();
|
||||
if(!selectable)
|
||||
showBoundingBox(false);
|
||||
}
|
||||
|
||||
SoSearchAction sa;
|
||||
sa.setInterest(SoSearchAction::ALL);
|
||||
sa.setSearchingAll(true);
|
||||
|
||||
@@ -94,7 +94,6 @@ protected:
|
||||
void setSelectable(bool Selectable=true);
|
||||
|
||||
virtual unsigned long getBoundColor() const;
|
||||
void applyBoundColor();
|
||||
|
||||
protected:
|
||||
SoMaterial * pcShapeMaterial;
|
||||
|
||||
Reference in New Issue
Block a user