From f784daf7f10a07adb82fff7fc84330457f6ab0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sun, 8 Nov 2015 09:34:51 +0100 Subject: [PATCH] Ensure claimchildren3d is always respected With the new setup object signals it may happen that a document object claims children but has no property changed after the viewprodivers creation. This scenario is not supportet up to now as the scene graph children are only set when the object changes. --- src/Gui/Document.cpp | 78 ++++++++++++++++++++++++-------------------- src/Gui/Document.h | 3 ++ 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index 439506b59c..af6413c60d 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -431,9 +431,12 @@ void Document::slotNewObject(const App::DocumentObject& Obj) if (activeView) activeView->getViewer()->addViewProvider(pcProvider); } - + // adding to the tree signalNewObject(*pcProvider); + + // it is possible that a new viewprovider aready claims children + handleChildren3D(pcProvider); } else { Base::Console().Warning("Gui::Document::slotNewObject() no view provider for the object %s found\n",cName.c_str()); @@ -473,7 +476,7 @@ void Document::slotDeletedObject(const App::DocumentObject& Obj) void Document::slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop) { - //Base::Console().Log("Document::slotChangedObject() called\n"); + //Base::Console().Log("Document::slotChangedObject() called\n"); ViewProvider* viewProvider = getViewProvider(&Obj); if (viewProvider) { try { @@ -492,39 +495,7 @@ void Document::slotChangedObject(const App::DocumentObject& Obj, const App::Prop Base::Console().Error("Cannot update representation for '%s'.\n", Obj.getNameInDocument()); } - // check for children - if (viewProvider->getChildRoot()) { - std::vector children = viewProvider->claimChildren3D(); - SoGroup* childGroup = viewProvider->getChildRoot(); - - // size not the same -> build up the list new - if(childGroup->getNumChildren() != static_cast(children.size())){ - - childGroup->removeAllChildren(); - - for(std::vector::iterator it=children.begin();it!=children.end();++it){ - ViewProvider* ChildViewProvider = getViewProvider(*it); - if(ChildViewProvider) { - SoSeparator* childRootNode = ChildViewProvider->getRoot(); - childGroup->addChild(childRootNode); - - // cycling to all views of the document to remove the viewprovider from the viewer itself - for (std::list::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { - View3DInventor *activeView = dynamic_cast(*vIt); - if (activeView && viewProvider && activeView->getViewer()->hasViewProvider(ChildViewProvider)) { - // Note about hasViewProvider() - //remove the viewprovider serves the purpose of detaching the inventor nodes from the - //top level root in the viewer. However, if some of the children were grouped beneath the object - //earlier they are not anymore part of the toplevel inventor node. we need to check for that. - if (d->_editViewProvider == ChildViewProvider) - resetEdit(); - activeView->getViewer()->removeViewProvider(ChildViewProvider); - } - } - } - } - } - } + handleChildren3D(viewProvider); if (viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) signalChangedObject(static_cast(*viewProvider), Prop); @@ -1392,3 +1363,40 @@ PyObject* Document::getPyObject(void) _pcDocPy->IncRef(); return _pcDocPy; } + +void Document::handleChildren3D(ViewProvider* viewProvider) +{ + // check for children + if (viewProvider->getChildRoot()) { + std::vector children = viewProvider->claimChildren3D(); + SoGroup* childGroup = viewProvider->getChildRoot(); + + // size not the same -> build up the list new + if(childGroup->getNumChildren() != static_cast(children.size())){ + + childGroup->removeAllChildren(); + + for(std::vector::iterator it=children.begin();it!=children.end();++it){ + ViewProvider* ChildViewProvider = getViewProvider(*it); + if(ChildViewProvider) { + SoSeparator* childRootNode = ChildViewProvider->getRoot(); + childGroup->addChild(childRootNode); + + // cycling to all views of the document to remove the viewprovider from the viewer itself + for (std::list::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { + View3DInventor *activeView = dynamic_cast(*vIt); + if (activeView && viewProvider && activeView->getViewer()->hasViewProvider(ChildViewProvider)) { + // Note about hasViewProvider() + //remove the viewprovider serves the purpose of detaching the inventor nodes from the + //top level root in the viewer. However, if some of the children were grouped beneath the object + //earlier they are not anymore part of the toplevel inventor node. we need to check for that. + if (d->_editViewProvider == ChildViewProvider) + resetEdit(); + activeView->getViewer()->removeViewProvider(ChildViewProvider); + } + } + } + } + } + } +} diff --git a/src/Gui/Document.h b/src/Gui/Document.h index 67f5160522..db0fd6ae9f 100644 --- a/src/Gui/Document.h +++ b/src/Gui/Document.h @@ -240,6 +240,9 @@ protected: Gui::DocumentPy *_pcDocPy; private: + //handles the scene graph nodes to correctly group child and parents + void handleChildren3D(ViewProvider* viewProvider); + struct DocumentP* d; static int _iDocCount;