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.
This commit is contained in:
Stefan Tröger 2015-11-08 09:34:51 +01:00
parent 35a5727474
commit 5f9bd72581
2 changed files with 46 additions and 35 deletions

View File

@ -431,9 +431,12 @@ void Document::slotNewObject(const App::DocumentObject& Obj)
if (activeView) if (activeView)
activeView->getViewer()->addViewProvider(pcProvider); activeView->getViewer()->addViewProvider(pcProvider);
} }
// adding to the tree // adding to the tree
signalNewObject(*pcProvider); signalNewObject(*pcProvider);
// it is possible that a new viewprovider aready claims children
handleChildren3D(pcProvider);
} }
else { else {
Base::Console().Warning("Gui::Document::slotNewObject() no view provider for the object %s found\n",cName.c_str()); 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) 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); ViewProvider* viewProvider = getViewProvider(&Obj);
if (viewProvider) { if (viewProvider) {
try { 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()); Base::Console().Error("Cannot update representation for '%s'.\n", Obj.getNameInDocument());
} }
// check for children handleChildren3D(viewProvider);
if (viewProvider->getChildRoot()) {
std::vector<App::DocumentObject*> children = viewProvider->claimChildren3D();
SoGroup* childGroup = viewProvider->getChildRoot();
// size not the same -> build up the list new
if(childGroup->getNumChildren() != static_cast<int>(children.size())){
childGroup->removeAllChildren();
for(std::vector<App::DocumentObject*>::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<Gui::BaseView*>::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) {
View3DInventor *activeView = dynamic_cast<View3DInventor *>(*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);
}
}
}
}
}
}
if (viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) if (viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId()))
signalChangedObject(static_cast<ViewProviderDocumentObject&>(*viewProvider), Prop); signalChangedObject(static_cast<ViewProviderDocumentObject&>(*viewProvider), Prop);
@ -1392,3 +1363,40 @@ PyObject* Document::getPyObject(void)
_pcDocPy->IncRef(); _pcDocPy->IncRef();
return _pcDocPy; return _pcDocPy;
} }
void Document::handleChildren3D(ViewProvider* viewProvider)
{
// check for children
if (viewProvider->getChildRoot()) {
std::vector<App::DocumentObject*> children = viewProvider->claimChildren3D();
SoGroup* childGroup = viewProvider->getChildRoot();
// size not the same -> build up the list new
if(childGroup->getNumChildren() != static_cast<int>(children.size())){
childGroup->removeAllChildren();
for(std::vector<App::DocumentObject*>::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<Gui::BaseView*>::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) {
View3DInventor *activeView = dynamic_cast<View3DInventor *>(*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);
}
}
}
}
}
}
}

View File

@ -240,6 +240,9 @@ protected:
Gui::DocumentPy *_pcDocPy; Gui::DocumentPy *_pcDocPy;
private: private:
//handles the scene graph nodes to correctly group child and parents
void handleChildren3D(ViewProvider* viewProvider);
struct DocumentP* d; struct DocumentP* d;
static int _iDocCount; static int _iDocCount;