Gui: code-refactoring
Split selection handling from View3DInventorViewer and move to View3DInventorSelection
This commit is contained in:
@@ -817,6 +817,7 @@ SET(View3D_CPP_SRCS
|
||||
View.cpp
|
||||
View3DInventor.cpp
|
||||
View3DInventorExamples.cpp
|
||||
View3DInventorSelection.cpp
|
||||
View3DInventorViewer.cpp
|
||||
View3DInventorRiftViewer.cpp
|
||||
CoinRiftWidget.cpp
|
||||
@@ -836,6 +837,7 @@ SET(View3D_SRCS
|
||||
View.h
|
||||
View3DInventor.h
|
||||
View3DInventorExamples.h
|
||||
View3DInventorSelection.h
|
||||
View3DInventorViewer.h
|
||||
View3DPy.h
|
||||
View3DInventorRiftViewer.h
|
||||
|
||||
277
src/Gui/View3DInventorSelection.cpp
Normal file
277
src/Gui/View3DInventorSelection.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/details/SoDetail.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoPickStyle.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
#endif
|
||||
|
||||
#include "Application.h"
|
||||
#include "Document.h"
|
||||
#include "SoFCUnifiedSelection.h"
|
||||
#include "View3DInventorSelection.h"
|
||||
#include "ViewProviderDocumentObject.h"
|
||||
#include <App/Document.h>
|
||||
#include <App/GeoFeatureGroupExtension.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
FC_LOG_LEVEL_INIT("3DViewerSelection",true,true)
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
View3DInventorSelection::View3DInventorSelection(SoFCUnifiedSelection* root)
|
||||
: selectionRoot(root)
|
||||
{
|
||||
selectionRoot->ref();
|
||||
|
||||
pcGroupOnTop = new SoSeparator;
|
||||
pcGroupOnTop->ref();
|
||||
root->addChild(pcGroupOnTop);
|
||||
|
||||
auto pcGroupOnTopPickStyle = new SoPickStyle;
|
||||
pcGroupOnTopPickStyle->style = SoPickStyle::UNPICKABLE;
|
||||
pcGroupOnTopPickStyle->setOverride(true);
|
||||
pcGroupOnTop->addChild(pcGroupOnTopPickStyle);
|
||||
|
||||
coin_setenv("COIN_SEPARATE_DIFFUSE_TRANSPARENCY_OVERRIDE", "1", TRUE);
|
||||
auto pcOnTopMaterial = new SoMaterial;
|
||||
pcOnTopMaterial->transparency = 0.5;
|
||||
pcOnTopMaterial->diffuseColor.setIgnored(true);
|
||||
pcOnTopMaterial->setOverride(true);
|
||||
pcGroupOnTop->addChild(pcOnTopMaterial);
|
||||
|
||||
{
|
||||
auto selRoot = new SoFCSelectionRoot;
|
||||
selRoot->selectionStyle = SoFCSelectionRoot::PassThrough;
|
||||
pcGroupOnTopSel = selRoot;
|
||||
pcGroupOnTopSel->setName("GroupOnTopSel");
|
||||
pcGroupOnTopSel->ref();
|
||||
pcGroupOnTop->addChild(pcGroupOnTopSel);
|
||||
}
|
||||
|
||||
{
|
||||
auto selRoot = new SoFCSelectionRoot;
|
||||
selRoot->selectionStyle = SoFCSelectionRoot::PassThrough;
|
||||
pcGroupOnTopPreSel = selRoot;
|
||||
pcGroupOnTopPreSel->setName("GroupOnTopPreSel");
|
||||
pcGroupOnTopPreSel->ref();
|
||||
pcGroupOnTop->addChild(pcGroupOnTopPreSel);
|
||||
}
|
||||
}
|
||||
|
||||
View3DInventorSelection::~View3DInventorSelection()
|
||||
{
|
||||
selectionRoot->unref();
|
||||
pcGroupOnTop->unref();
|
||||
pcGroupOnTopPreSel->unref();
|
||||
pcGroupOnTopSel->unref();
|
||||
}
|
||||
|
||||
void View3DInventorSelection::checkGroupOnTop(const SelectionChanges &Reason)
|
||||
{
|
||||
if (Reason.Type == SelectionChanges::SetSelection || Reason.Type == SelectionChanges::ClrSelection) {
|
||||
clearGroupOnTop();
|
||||
if(Reason.Type == SelectionChanges::ClrSelection)
|
||||
return;
|
||||
}
|
||||
if(Reason.Type == SelectionChanges::RmvPreselect ||
|
||||
Reason.Type == SelectionChanges::RmvPreselectSignal)
|
||||
{
|
||||
SoSelectionElementAction action(SoSelectionElementAction::None,true);
|
||||
action.apply(pcGroupOnTopPreSel);
|
||||
coinRemoveAllChildren(pcGroupOnTopPreSel);
|
||||
objectsOnTopPreSel.clear();
|
||||
return;
|
||||
}
|
||||
if(!getDocument() || !Reason.pDocName || !Reason.pDocName[0] || !Reason.pObjectName)
|
||||
return;
|
||||
auto obj = getDocument()->getDocument()->getObject(Reason.pObjectName);
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
return;
|
||||
std::string key(obj->getNameInDocument());
|
||||
key += '.';
|
||||
auto subname = Reason.pSubName;
|
||||
if(subname)
|
||||
key += subname;
|
||||
if(Reason.Type == SelectionChanges::RmvSelection) {
|
||||
auto &objs = objectsOnTop;
|
||||
auto pcGroup = pcGroupOnTopSel;
|
||||
auto it = objs.find(key.c_str());
|
||||
if(it == objs.end())
|
||||
return;
|
||||
int index = pcGroup->findChild(it->second);
|
||||
if(index >= 0) {
|
||||
auto node = static_cast<SoFCPathAnnotation*>(it->second);
|
||||
SoSelectionElementAction action(node->getDetail()?
|
||||
SoSelectionElementAction::Remove:SoSelectionElementAction::None,true);
|
||||
auto path = node->getPath();
|
||||
SoTempPath tmpPath(2 + (path ? path->getLength() : 0));
|
||||
tmpPath.ref();
|
||||
tmpPath.append(pcGroup);
|
||||
tmpPath.append(node);
|
||||
tmpPath.append(node->getPath());
|
||||
action.setElement(node->getDetail());
|
||||
action.apply(&tmpPath);
|
||||
tmpPath.unrefNoDelete();
|
||||
pcGroup->removeChild(index);
|
||||
FC_LOG("remove annotation " << Reason.Type << " " << key);
|
||||
}else
|
||||
FC_LOG("remove annotation object " << Reason.Type << " " << key);
|
||||
objs.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
auto &objs = Reason.Type==SelectionChanges::SetPreselect?objectsOnTopPreSel:objectsOnTop;
|
||||
auto pcGroup = Reason.Type==SelectionChanges::SetPreselect?pcGroupOnTopPreSel:pcGroupOnTopSel;
|
||||
|
||||
if(objs.find(key.c_str())!=objs.end())
|
||||
return;
|
||||
auto vp = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(obj));
|
||||
if(!vp || !vp->isSelectable() || !vp->isShow())
|
||||
return;
|
||||
auto svp = vp;
|
||||
if(subname && *subname) {
|
||||
auto sobj = obj->getSubObject(subname);
|
||||
if(!sobj || !sobj->getNameInDocument())
|
||||
return;
|
||||
if(sobj!=obj) {
|
||||
svp = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(sobj));
|
||||
if(!svp || !svp->isSelectable())
|
||||
return;
|
||||
}
|
||||
}
|
||||
int onTop;
|
||||
// onTop==2 means on top only if whole object is selected,
|
||||
// onTop==3 means on top only if some sub-element is selected
|
||||
// onTop==1 means either
|
||||
if(Gui::Selection().needPickedList())
|
||||
onTop = 1;
|
||||
else if(vp->OnTopWhenSelected.getValue())
|
||||
onTop = vp->OnTopWhenSelected.getValue();
|
||||
else
|
||||
onTop = svp->OnTopWhenSelected.getValue();
|
||||
if(Reason.Type == SelectionChanges::SetPreselect) {
|
||||
SoHighlightElementAction action;
|
||||
action.setHighlighted(true);
|
||||
action.setColor(selectionRoot->colorHighlight.getValue());
|
||||
action.apply(pcGroupOnTopPreSel);
|
||||
if(!onTop)
|
||||
onTop = 2;
|
||||
}else {
|
||||
if(!onTop)
|
||||
return;
|
||||
SoSelectionElementAction action(SoSelectionElementAction::All);
|
||||
action.setColor(selectionRoot->colorHighlight.getValue());
|
||||
action.apply(pcGroupOnTopSel);
|
||||
}
|
||||
if(onTop==2 || onTop==3) {
|
||||
if(subname && *subname) {
|
||||
size_t len = strlen(subname);
|
||||
if(subname[len-1]=='.') {
|
||||
// ending with '.' means whole object selection
|
||||
if(onTop == 3)
|
||||
return;
|
||||
}else if(onTop==2)
|
||||
return;
|
||||
}else if(onTop==3)
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<ViewProvider*> groups;
|
||||
auto grpVp = vp;
|
||||
for(auto childVp=vp;;childVp=grpVp) {
|
||||
auto grp = App::GeoFeatureGroupExtension::getGroupOfObject(childVp->getObject());
|
||||
if(!grp || !grp->getNameInDocument()) break;
|
||||
grpVp = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(grp));
|
||||
if(!grpVp) break;
|
||||
auto childRoot = grpVp->getChildRoot();
|
||||
auto modeSwitch = grpVp->getModeSwitch();
|
||||
auto idx = modeSwitch->whichChild.getValue();
|
||||
if(idx<0 || idx>=modeSwitch->getNumChildren() ||
|
||||
modeSwitch->getChild(idx)!=childRoot)
|
||||
{
|
||||
FC_LOG("skip " << obj->getFullName() << '.' << (subname?subname:"")
|
||||
<< ", hidden inside geo group");
|
||||
return;
|
||||
}
|
||||
if(childRoot->findChild(childVp->getRoot())<0) {
|
||||
FC_LOG("cannot find '" << childVp->getObject()->getFullName()
|
||||
<< "' in geo group '" << grp->getNameInDocument() << "'");
|
||||
break;
|
||||
}
|
||||
groups.push_back(grpVp);
|
||||
}
|
||||
|
||||
SoTempPath path(10);
|
||||
path.ref();
|
||||
|
||||
for(auto it=groups.rbegin();it!=groups.rend();++it) {
|
||||
auto grpVp = *it;
|
||||
path.append(grpVp->getRoot());
|
||||
path.append(grpVp->getModeSwitch());
|
||||
path.append(grpVp->getChildRoot());
|
||||
}
|
||||
|
||||
SoDetail *det = nullptr;
|
||||
if(vp->getDetailPath(subname, &path,true,det) && path.getLength()) {
|
||||
auto node = new SoFCPathAnnotation;
|
||||
node->setPath(&path);
|
||||
pcGroup->addChild(node);
|
||||
if(det) {
|
||||
SoSelectionElementAction action(SoSelectionElementAction::Append,true);
|
||||
action.setElement(det);
|
||||
SoTempPath tmpPath(path.getLength()+2);
|
||||
tmpPath.ref();
|
||||
tmpPath.append(pcGroup);
|
||||
tmpPath.append(node);
|
||||
tmpPath.append(&path);
|
||||
action.apply(&tmpPath);
|
||||
tmpPath.unrefNoDelete();
|
||||
node->setDetail(det);
|
||||
det = nullptr;
|
||||
}
|
||||
FC_LOG("add annotation " << Reason.Type << " " << key);
|
||||
objs[key.c_str()] = node;
|
||||
}
|
||||
delete det;
|
||||
path.unrefNoDelete();
|
||||
}
|
||||
|
||||
void View3DInventorSelection::clearGroupOnTop()
|
||||
{
|
||||
if(!objectsOnTop.empty() || !objectsOnTopPreSel.empty()) {
|
||||
objectsOnTop.clear();
|
||||
objectsOnTopPreSel.clear();
|
||||
SoSelectionElementAction action(SoSelectionElementAction::None,true);
|
||||
action.apply(pcGroupOnTopPreSel);
|
||||
action.apply(pcGroupOnTopSel);
|
||||
coinRemoveAllChildren(pcGroupOnTopSel);
|
||||
coinRemoveAllChildren(pcGroupOnTopPreSel);
|
||||
FC_LOG("clear annotation");
|
||||
}
|
||||
}
|
||||
67
src/Gui/View3DInventorSelection.h
Normal file
67
src/Gui/View3DInventorSelection.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef GUI_VIEW3DINVENTORSELECTION_H
|
||||
#define GUI_VIEW3DINVENTORSELECTION_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <Gui/Selection.h>
|
||||
|
||||
class SoGroup;
|
||||
class SoNode;
|
||||
class SoSeparator;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class Document;
|
||||
class SoFCUnifiedSelection;
|
||||
|
||||
class GuiExport View3DInventorSelection
|
||||
{
|
||||
public:
|
||||
View3DInventorSelection(SoFCUnifiedSelection* root);
|
||||
~View3DInventorSelection();
|
||||
|
||||
void setDocument(Gui::Document *pcDocument) {
|
||||
guiDocument = pcDocument;
|
||||
}
|
||||
Gui::Document* getDocument() const {
|
||||
return guiDocument;
|
||||
}
|
||||
|
||||
void checkGroupOnTop(const SelectionChanges &Reason);
|
||||
void clearGroupOnTop();
|
||||
|
||||
private:
|
||||
SoGroup * pcGroupOnTop;
|
||||
SoGroup * pcGroupOnTopSel;
|
||||
SoGroup * pcGroupOnTopPreSel;
|
||||
SoFCUnifiedSelection* selectionRoot;
|
||||
std::map<std::string, SoNode*> objectsOnTop;
|
||||
std::map<std::string, SoNode*> objectsOnTopPreSel;
|
||||
Gui::Document* guiDocument = nullptr;
|
||||
};
|
||||
|
||||
} //namespace Gui
|
||||
|
||||
#endif // GUI_VIEW3DINVENTORSELECTION_H
|
||||
@@ -427,34 +427,7 @@ void View3DInventorViewer::init()
|
||||
pcViewProviderRoot->addChild(cb);
|
||||
#endif
|
||||
|
||||
pcGroupOnTop = new SoSeparator;
|
||||
pcGroupOnTop->ref();
|
||||
pcViewProviderRoot->addChild(pcGroupOnTop);
|
||||
|
||||
auto pcGroupOnTopPickStyle = new SoPickStyle;
|
||||
pcGroupOnTopPickStyle->style = SoPickStyle::UNPICKABLE;
|
||||
pcGroupOnTopPickStyle->setOverride(true);
|
||||
pcGroupOnTop->addChild(pcGroupOnTopPickStyle);
|
||||
|
||||
coin_setenv("COIN_SEPARATE_DIFFUSE_TRANSPARENCY_OVERRIDE", "1", TRUE);
|
||||
auto pcOnTopMaterial = new SoMaterial;
|
||||
pcOnTopMaterial->transparency = 0.5;
|
||||
pcOnTopMaterial->diffuseColor.setIgnored(true);
|
||||
pcOnTopMaterial->setOverride(true);
|
||||
pcGroupOnTop->addChild(pcOnTopMaterial);
|
||||
|
||||
auto selRoot = new SoFCSelectionRoot;
|
||||
selRoot->selectionStyle = SoFCSelectionRoot::PassThrough;
|
||||
pcGroupOnTopSel = selRoot;
|
||||
pcGroupOnTopSel->setName("GroupOnTopSel");
|
||||
pcGroupOnTopSel->ref();
|
||||
pcGroupOnTop->addChild(pcGroupOnTopSel);
|
||||
selRoot = new SoFCSelectionRoot;
|
||||
selRoot->selectionStyle = SoFCSelectionRoot::PassThrough;
|
||||
pcGroupOnTopPreSel = selRoot;
|
||||
pcGroupOnTopPreSel->setName("GroupOnTopPreSel");
|
||||
pcGroupOnTopPreSel->ref();
|
||||
pcGroupOnTop->addChild(pcGroupOnTopPreSel);
|
||||
inventorSelection = std::make_unique<View3DInventorSelection>(selectionRoot);
|
||||
|
||||
pcClipPlane = nullptr;
|
||||
|
||||
@@ -558,14 +531,12 @@ View3DInventorViewer::~View3DInventorViewer()
|
||||
this->backlight->unref();
|
||||
this->backlight = nullptr;
|
||||
|
||||
this->pcGroupOnTop->unref();
|
||||
this->pcGroupOnTopPreSel->unref();
|
||||
this->pcGroupOnTopSel->unref();
|
||||
inventorSelection.reset(nullptr);
|
||||
|
||||
this->pcEditingRoot->unref();
|
||||
this->pcEditingTransform->unref();
|
||||
|
||||
if(this->pcClipPlane)
|
||||
if (this->pcClipPlane)
|
||||
this->pcClipPlane->unref();
|
||||
|
||||
delete this->navigation;
|
||||
@@ -639,6 +610,7 @@ void View3DInventorViewer::setDocument(Gui::Document* pcDocument)
|
||||
// write the document the viewer belongs to the selection node
|
||||
guiDocument = pcDocument;
|
||||
selectionRoot->pcDocument = pcDocument;
|
||||
inventorSelection->setDocument(pcDocument);
|
||||
|
||||
if(pcDocument) {
|
||||
const auto &sels = Selection().getSelection(pcDocument->getDocument()->getName(), ResolveMode::NoResolve);
|
||||
@@ -664,191 +636,6 @@ void View3DInventorViewer::initialize()
|
||||
this->axiscrossSize = 10;
|
||||
}
|
||||
|
||||
void View3DInventorViewer::clearGroupOnTop() {
|
||||
if(!objectsOnTop.empty() || !objectsOnTopPreSel.empty()) {
|
||||
objectsOnTop.clear();
|
||||
objectsOnTopPreSel.clear();
|
||||
SoSelectionElementAction action(SoSelectionElementAction::None,true);
|
||||
action.apply(pcGroupOnTopPreSel);
|
||||
action.apply(pcGroupOnTopSel);
|
||||
coinRemoveAllChildren(pcGroupOnTopSel);
|
||||
coinRemoveAllChildren(pcGroupOnTopPreSel);
|
||||
FC_LOG("clear annotation");
|
||||
}
|
||||
}
|
||||
|
||||
void View3DInventorViewer::checkGroupOnTop(const SelectionChanges &Reason) {
|
||||
if(Reason.Type == SelectionChanges::SetSelection || Reason.Type == SelectionChanges::ClrSelection) {
|
||||
clearGroupOnTop();
|
||||
if(Reason.Type == SelectionChanges::ClrSelection)
|
||||
return;
|
||||
}
|
||||
if(Reason.Type == SelectionChanges::RmvPreselect ||
|
||||
Reason.Type == SelectionChanges::RmvPreselectSignal)
|
||||
{
|
||||
SoSelectionElementAction action(SoSelectionElementAction::None,true);
|
||||
action.apply(pcGroupOnTopPreSel);
|
||||
coinRemoveAllChildren(pcGroupOnTopPreSel);
|
||||
objectsOnTopPreSel.clear();
|
||||
return;
|
||||
}
|
||||
if(!getDocument() || !Reason.pDocName || !Reason.pDocName[0] || !Reason.pObjectName)
|
||||
return;
|
||||
auto obj = getDocument()->getDocument()->getObject(Reason.pObjectName);
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
return;
|
||||
std::string key(obj->getNameInDocument());
|
||||
key += '.';
|
||||
auto subname = Reason.pSubName;
|
||||
if(subname)
|
||||
key += subname;
|
||||
if(Reason.Type == SelectionChanges::RmvSelection) {
|
||||
auto &objs = objectsOnTop;
|
||||
auto pcGroup = pcGroupOnTopSel;
|
||||
auto it = objs.find(key.c_str());
|
||||
if(it == objs.end())
|
||||
return;
|
||||
int index = pcGroup->findChild(it->second);
|
||||
if(index >= 0) {
|
||||
auto node = static_cast<SoFCPathAnnotation*>(it->second);
|
||||
SoSelectionElementAction action(node->getDetail()?
|
||||
SoSelectionElementAction::Remove:SoSelectionElementAction::None,true);
|
||||
auto path = node->getPath();
|
||||
SoTempPath tmpPath(2 + (path ? path->getLength() : 0));
|
||||
tmpPath.ref();
|
||||
tmpPath.append(pcGroup);
|
||||
tmpPath.append(node);
|
||||
tmpPath.append(node->getPath());
|
||||
action.setElement(node->getDetail());
|
||||
action.apply(&tmpPath);
|
||||
tmpPath.unrefNoDelete();
|
||||
pcGroup->removeChild(index);
|
||||
FC_LOG("remove annotation " << Reason.Type << " " << key);
|
||||
}else
|
||||
FC_LOG("remove annotation object " << Reason.Type << " " << key);
|
||||
objs.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
auto &objs = Reason.Type==SelectionChanges::SetPreselect?objectsOnTopPreSel:objectsOnTop;
|
||||
auto pcGroup = Reason.Type==SelectionChanges::SetPreselect?pcGroupOnTopPreSel:pcGroupOnTopSel;
|
||||
|
||||
if(objs.find(key.c_str())!=objs.end())
|
||||
return;
|
||||
auto vp = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(obj));
|
||||
if(!vp || !vp->isSelectable() || !vp->isShow())
|
||||
return;
|
||||
auto svp = vp;
|
||||
if(subname && *subname) {
|
||||
auto sobj = obj->getSubObject(subname);
|
||||
if(!sobj || !sobj->getNameInDocument())
|
||||
return;
|
||||
if(sobj!=obj) {
|
||||
svp = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(sobj));
|
||||
if(!svp || !svp->isSelectable())
|
||||
return;
|
||||
}
|
||||
}
|
||||
int onTop;
|
||||
// onTop==2 means on top only if whole object is selected,
|
||||
// onTop==3 means on top only if some sub-element is selected
|
||||
// onTop==1 means either
|
||||
if(Gui::Selection().needPickedList())
|
||||
onTop = 1;
|
||||
else if(vp->OnTopWhenSelected.getValue())
|
||||
onTop = vp->OnTopWhenSelected.getValue();
|
||||
else
|
||||
onTop = svp->OnTopWhenSelected.getValue();
|
||||
if(Reason.Type == SelectionChanges::SetPreselect) {
|
||||
SoHighlightElementAction action;
|
||||
action.setHighlighted(true);
|
||||
action.setColor(selectionRoot->colorHighlight.getValue());
|
||||
action.apply(pcGroupOnTopPreSel);
|
||||
if(!onTop)
|
||||
onTop = 2;
|
||||
}else {
|
||||
if(!onTop)
|
||||
return;
|
||||
SoSelectionElementAction action(SoSelectionElementAction::All);
|
||||
action.setColor(selectionRoot->colorSelection.getValue());
|
||||
action.apply(pcGroupOnTopSel);
|
||||
}
|
||||
if(onTop==2 || onTop==3) {
|
||||
if(subname && *subname) {
|
||||
size_t len = strlen(subname);
|
||||
if(subname[len-1]=='.') {
|
||||
// ending with '.' means whole object selection
|
||||
if(onTop == 3)
|
||||
return;
|
||||
}else if(onTop==2)
|
||||
return;
|
||||
}else if(onTop==3)
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<ViewProvider*> groups;
|
||||
auto grpVp = vp;
|
||||
for(auto childVp=vp;;childVp=grpVp) {
|
||||
auto grp = App::GeoFeatureGroupExtension::getGroupOfObject(childVp->getObject());
|
||||
if(!grp || !grp->getNameInDocument()) break;
|
||||
grpVp = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(grp));
|
||||
if(!grpVp) break;
|
||||
auto childRoot = grpVp->getChildRoot();
|
||||
auto modeSwitch = grpVp->getModeSwitch();
|
||||
auto idx = modeSwitch->whichChild.getValue();
|
||||
if(idx<0 || idx>=modeSwitch->getNumChildren() ||
|
||||
modeSwitch->getChild(idx)!=childRoot)
|
||||
{
|
||||
FC_LOG("skip " << obj->getFullName() << '.' << (subname?subname:"")
|
||||
<< ", hidden inside geo group");
|
||||
return;
|
||||
}
|
||||
if(childRoot->findChild(childVp->getRoot())<0) {
|
||||
FC_LOG("cannot find '" << childVp->getObject()->getFullName()
|
||||
<< "' in geo group '" << grp->getNameInDocument() << "'");
|
||||
break;
|
||||
}
|
||||
groups.push_back(grpVp);
|
||||
}
|
||||
|
||||
SoTempPath path(10);
|
||||
path.ref();
|
||||
|
||||
for(auto it=groups.rbegin();it!=groups.rend();++it) {
|
||||
auto grpVp = *it;
|
||||
path.append(grpVp->getRoot());
|
||||
path.append(grpVp->getModeSwitch());
|
||||
path.append(grpVp->getChildRoot());
|
||||
}
|
||||
|
||||
SoDetail *det = nullptr;
|
||||
if(vp->getDetailPath(subname, &path,true,det) && path.getLength()) {
|
||||
auto node = new SoFCPathAnnotation;
|
||||
node->setPath(&path);
|
||||
pcGroup->addChild(node);
|
||||
if(det) {
|
||||
SoSelectionElementAction action(SoSelectionElementAction::Append,true);
|
||||
action.setElement(det);
|
||||
SoTempPath tmpPath(path.getLength()+2);
|
||||
tmpPath.ref();
|
||||
tmpPath.append(pcGroup);
|
||||
tmpPath.append(node);
|
||||
tmpPath.append(&path);
|
||||
action.apply(&tmpPath);
|
||||
tmpPath.unrefNoDelete();
|
||||
node->setDetail(det);
|
||||
det = nullptr;
|
||||
}
|
||||
FC_LOG("add annotation " << Reason.Type << " " << key);
|
||||
objs[key.c_str()] = node;
|
||||
}
|
||||
delete det;
|
||||
path.unrefNoDelete();
|
||||
}
|
||||
|
||||
/// @cond DOXERR
|
||||
void View3DInventorViewer::onSelectionChanged(const SelectionChanges &_Reason)
|
||||
{
|
||||
@@ -879,7 +666,7 @@ void View3DInventorViewer::onSelectionChanged(const SelectionChanges &_Reason)
|
||||
case SelectionChanges::AddSelection:
|
||||
case SelectionChanges::RmvSelection:
|
||||
case SelectionChanges::ClrSelection:
|
||||
checkGroupOnTop(Reason);
|
||||
inventorSelection->checkGroupOnTop(Reason);
|
||||
break;
|
||||
case SelectionChanges::SetPreselectSignal:
|
||||
break;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
@@ -40,6 +41,7 @@
|
||||
|
||||
#include "Namespace.h"
|
||||
#include "Selection.h"
|
||||
#include "View3DInventorSelection.h"
|
||||
#include "Quarter/SoQTQuarterAdaptor.h"
|
||||
|
||||
|
||||
@@ -139,8 +141,6 @@ public:
|
||||
|
||||
/// Observer message from the Selection
|
||||
void onSelectionChanged(const SelectionChanges &Reason) override;
|
||||
void checkGroupOnTop(const SelectionChanges &Reason);
|
||||
void clearGroupOnTop();
|
||||
|
||||
SoDirectionalLight* getBacklight() const;
|
||||
void setBacklight(SbBool on);
|
||||
@@ -449,11 +449,7 @@ private:
|
||||
|
||||
SoSeparator * pcViewProviderRoot;
|
||||
|
||||
SoGroup * pcGroupOnTop;
|
||||
SoGroup * pcGroupOnTopSel;
|
||||
SoGroup * pcGroupOnTopPreSel;
|
||||
std::map<std::string,SoNode*> objectsOnTop;
|
||||
std::map<std::string,SoNode*> objectsOnTopPreSel;
|
||||
std::unique_ptr<View3DInventorSelection> inventorSelection;
|
||||
|
||||
SoSeparator * pcEditingRoot;
|
||||
SoTransform * pcEditingTransform;
|
||||
|
||||
Reference in New Issue
Block a user