diff --git a/cmake_support/OST.cmake b/cmake_support/OST.cmake index ed57c7400d716f16d804090eae93d3c9c0ae0c64..10ec36703b5dd3d278461f4e35ea9aeb01f5c218 100644 --- a/cmake_support/OST.cmake +++ b/cmake_support/OST.cmake @@ -531,7 +531,7 @@ macro(ost_unittest MODULE SOURCE_FILES) target_link_libraries(${_test_name} ${BOOST_UNIT_TEST_LIBRARIES} "ost_${MODULE}") add_custom_target("${_test_name}_run" - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${_test_name} || echo + COMMAND OST_ROOT=${STAGE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${_test_name} || echo WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "running checks for module ${MODULE}" DEPENDS ${_test_name}) diff --git a/modules/gfx/pymod/export_gfx_node.cc b/modules/gfx/pymod/export_gfx_node.cc index b7791e8e67e51232d3988876d2b44d6a697fb179..07195c10050a85eed874e4d299fcf33bbdb76ba3 100644 --- a/modules/gfx/pymod/export_gfx_node.cc +++ b/modules/gfx/pymod/export_gfx_node.cc @@ -31,7 +31,8 @@ void export_GfxNode() void (GfxNode::* node_rem2)(GfxNodeP) = &GfxNode::Remove; void (GfxNode::* node_rem3)(const String&) = &GfxNode::Remove; - class_<GfxNode, boost::noncopyable>("GfxNode",no_init) + class_<GfxNode, GfxNodeP, + boost::noncopyable>("GfxNode", init<const String&>()) .def("GetName",&GfxNode::GetName) .def("Hide",&GfxNode::Hide) .def("Show",&GfxNode::Show) @@ -43,5 +44,4 @@ void export_GfxNode() .def("Remove",node_rem2) .def("Remove",node_rem3) ; - register_ptr_to_python<GfxNodeP>(); } diff --git a/modules/gfx/src/gfx_node.cc b/modules/gfx/src/gfx_node.cc index d4ba1d11740e626e916a35c2e849fedb304749f0..76a513dc732613a3951a94c729690be5bab6f29e 100644 --- a/modules/gfx/src/gfx_node.cc +++ b/modules/gfx/src/gfx_node.cc @@ -101,45 +101,94 @@ void GfxNode::Rename(const String& name) Scene::Instance().ObjectChanged(name_); } +bool GfxNode::IsAttachedToScene() const +{ + GfxNodeP root=Scene::Instance().GetRootNode(); + if (root==this->shared_from_this()) { return true; } + GfxNodeP parent=this->GetParent(); + while (parent) { + if (parent==root) { + return true; + } + parent=parent->GetParent(); + } + return false; +} + void GfxNode::Add(GfxObjP obj) { - node_vector_.push_back(obj); - Scene::Instance().NodeAdded(obj); + GfxNodeP node=obj; + this->Add(obj); } void GfxNode::Remove(GfxObjP obj) { - GfxNodeVector::iterator it = find (node_vector_.begin(), node_vector_.end(), obj); + GfxNodeVector::iterator it = find(node_vector_.begin(), + node_vector_.end(), obj); if(it!=node_vector_.end()) { node_vector_.erase(it); + obj->parent_.reset(); + if (this->IsAttachedToScene()) { + Scene::Instance().NotifyObservers(bind(&SceneObserver::NodeRemoved, + _1, obj)); + } } + } + using boost::bind; + + void GfxNode::RemoveAll() { - GfxNodeVector v=node_vector_; - node_vector_.clear(); - for (GfxNodeVector::iterator i=v.begin(), e=v.end(); i!=e; ++i) { - if (GfxObjP o=dyn_cast<GfxObj>(*i)) { - Scene::Instance().NotifyObservers(bind(&SceneObserver::NodeRemoved, _1, o)); - } + bool attached=this->IsAttachedToScene(); + for (GfxNodeVector::iterator i=node_vector_.begin(), + e=node_vector_.end(); i!=e; ++i) { + (*i)->parent_.reset(); + if (!attached) + continue; + Scene::Instance().NotifyObservers(bind(&SceneObserver::NodeRemoved, + _1, *i)); } + node_vector_.clear(); } void GfxNode::Add(GfxNodeP node) { node_vector_.push_back(node); - Scene::Instance().NodeAdded(node); + if (!node->parent_.expired()) { + node->GetParent()->Remove(node); + } + node->parent_=this->shared_from_this(); + if (this->IsAttachedToScene()) { + Scene::Instance().NodeAdded(node); + } } void GfxNode::Remove(GfxNodeP node) { - GfxNodeVector::iterator it = find (node_vector_.begin(), node_vector_.end(), node); + GfxNodeVector::iterator it=std::find(node_vector_.begin(), + node_vector_.end(), node); if(it!=node_vector_.end()) { + node->parent_=GfxNodeP(); node_vector_.erase(it); } + if (this->IsAttachedToScene()) { + Scene::Instance().NotifyObservers(bind(&SceneObserver::NodeRemoved, + _1, node)); + } +} + +gfx::GfxNodeP GfxNode::GetParent() const +{ + if (parent_.expired()) { + return gfx::GfxNodeP(); + } + return parent_.lock(); } + + void GfxNode::Remove(const String& name) { GfxNodeVector::iterator node; diff --git a/modules/gfx/src/gfx_node.hh b/modules/gfx/src/gfx_node.hh index 4f3ceaf1f9614d3b6532659878d32770ecb47679..9bec738a57c931ba729f9e9dc708911a1d294950 100644 --- a/modules/gfx/src/gfx_node.hh +++ b/modules/gfx/src/gfx_node.hh @@ -98,15 +98,25 @@ class DLLEXPORT_OST_GFX GfxNode: public boost::enable_shared_from_this<GfxNode> bool IsVisible() const; virtual void ContextSwitch(); - + + /// \brief whether the node (or one of it's parents) has been added to the + /// scene + bool IsAttachedToScene() const; + + + gfx::GfxNodeP GetParent() const; + + const GfxNodeVector& GetChildren() const { return node_vector_; } + GfxNodeVector& GetChildren() { return node_vector_; } private: GfxNode(const GfxNode& o); GfxNode& operator=(const GfxNode&); - String name_; - bool show_; - GfxNodeVector node_vector_; + String name_; + bool show_; + GfxNodeVector node_vector_; + boost::weak_ptr<GfxNode> parent_; }; }} diff --git a/modules/gfx/tests/CMakeLists.txt b/modules/gfx/tests/CMakeLists.txt index eff4ec11fa761b2dab392c8bd06c8e4952c8f249..227b9ff8dc2f15c51408a90e6d58b0768ef86a28 100644 --- a/modules/gfx/tests/CMakeLists.txt +++ b/modules/gfx/tests/CMakeLists.txt @@ -1,5 +1,6 @@ set(OST_GFX_UNIT_TESTS tests.cc + test_gfx_node.cc ) if (ENABLE_IMG) list(APPEND OST_GFX_UNIT_TESTS test_map_octree.cc) diff --git a/modules/gfx/tests/test_gfx_node.cc b/modules/gfx/tests/test_gfx_node.cc new file mode 100644 index 0000000000000000000000000000000000000000..361b9a2f28a3665fe606c7f798b04df2734347db --- /dev/null +++ b/modules/gfx/tests/test_gfx_node.cc @@ -0,0 +1,166 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 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 Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ + +/* + Author: Marco Biasini + */ +#include <ost/string_ref.hh> +#include <ost/platform.hh> +#include <ost/gfx/gfx_node.hh> +#include <ost/gfx/gfx_object.hh> +#include <ost/gfx/scene.hh> +#define BOOST_TEST_DYN_LINK +#include <boost/test/unit_test.hpp> + + +using boost::unit_test_framework::test_suite; +using namespace ost; +using namespace ost::gfx; + +// small RAII class to setup environment for unit tests. even though we don't +// use any of the rendering functionality, we still need to initialize an +// offscreen buffer on mac to avoid segfaults. +struct GfxTestEnv { + GfxTestEnv() + { + // we know OST_ROOT is set for unit tests + SetPrefixPath(getenv("OST_ROOT")); + Scene::Instance().StartOffscreenMode(100, 100); + } + + ~GfxTestEnv() + { + Scene::Instance().StopOffscreenMode(); + } + +}; + + +struct Observer : public SceneObserver { + Observer(): added_count(0),removed_count(0) {} + + virtual void NodeAdded(const GfxNodeP& node) + { + added_count+=1; + } + + virtual void NodeRemoved(const GfxNodeP& node) + { + removed_count+=1; + } + + int added_count; + int removed_count; +}; + +BOOST_AUTO_TEST_SUITE(gfx_node) + +BOOST_AUTO_TEST_CASE(gfx_node_add) +{ + GfxNodeP n1(new GfxNode("1")); + BOOST_CHECK_EQUAL(n1->GetParent(), GfxNodeP()); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 0); + GfxNodeP n2(new GfxNode("2")); + n1->Add(n2); + BOOST_CHECK_EQUAL(n1->GetParent(), GfxNodeP()); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 1); + BOOST_CHECK_EQUAL(n2->GetParent(), n1); + BOOST_CHECK_EQUAL(n2->GetChildCount(), 0); + + // "move" node 2 from 1 to 3 + GfxNodeP n3(new GfxNode("3")); + n3->Add(n2); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 0); + BOOST_CHECK_EQUAL(n2->GetParent(), n3); + BOOST_CHECK_EQUAL(n3->GetChildCount(), 1); +} + + +BOOST_AUTO_TEST_CASE(gfx_node_remove) +{ + GfxNodeP n1(new GfxNode("1")); + BOOST_CHECK_EQUAL(n1->GetParent(), GfxNodeP()); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 0); + GfxNodeP n2(new GfxNode("2")); + n1->Add(n2); + n1->Remove(n2); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 0); + BOOST_CHECK_EQUAL(n2->GetParent(), GfxNodeP()); +} + +BOOST_AUTO_TEST_CASE(gfx_node_remove_all) +{ + GfxNodeP n1(new GfxNode("1")); + BOOST_CHECK_EQUAL(n1->GetParent(), GfxNodeP()); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 0); + GfxNodeP n2(new GfxNode("2")); + GfxNodeP n3(new GfxNode("3")); + GfxNodeP n4(new GfxNode("4")); + n1->Add(n2); + n1->Add(n3); + n1->Add(n4); + n1->RemoveAll(); + BOOST_CHECK_EQUAL(n1->GetChildCount(), 0); + BOOST_CHECK_EQUAL(n2->GetParent(), GfxNodeP()); +} + +BOOST_AUTO_TEST_CASE(is_attached_to_scene) +{ + GfxTestEnv env; + Scene::Instance().RemoveAll(); + GfxNodeP n1(new GfxNode("1")); + GfxNodeP n2(new GfxNode("2")); + n1->Add(n2); + BOOST_CHECK(!n1->IsAttachedToScene()); + BOOST_CHECK(!n2->IsAttachedToScene()); + + Scene::Instance().Add(n1); + BOOST_CHECK(n1->IsAttachedToScene()); + BOOST_CHECK(n2->IsAttachedToScene()); + + // root node is always connected to scene! + BOOST_CHECK(Scene::Instance().GetRootNode()->IsAttachedToScene()); +} + +BOOST_AUTO_TEST_CASE(observe_added_removed) +{ + GfxTestEnv env; + Observer o1; + Scene::Instance().RemoveAll(); + Scene::Instance().AttachObserver(&o1); + GfxNodeP n1(new GfxNode("1")); + GfxNodeP n2(new GfxNode("2")); + GfxNodeP n3(new GfxNode("3")); + n1->Add(n2); + BOOST_CHECK_EQUAL(o1.added_count, 0); + BOOST_CHECK_EQUAL(o1.removed_count, 0); + Scene::Instance().Add(n1); + BOOST_CHECK_EQUAL(o1.added_count, 1); + BOOST_CHECK_EQUAL(o1.removed_count, 0); + n2->Add(n3); + BOOST_CHECK_EQUAL(o1.added_count, 2); + BOOST_CHECK_EQUAL(o1.removed_count, 0); + n2->Remove(n3); + BOOST_CHECK_EQUAL(o1.added_count, 2); + BOOST_CHECK_EQUAL(o1.removed_count, 1); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/modules/gui/src/scene_win/current_selection_node.cc b/modules/gui/src/scene_win/current_selection_node.cc index 9de4397a43989be2af8d4732e08f0adec8974f02..6f7eeddaae4d8be145d2b5e47a96e2782e1fbf20 100644 --- a/modules/gui/src/scene_win/current_selection_node.cc +++ b/modules/gui/src/scene_win/current_selection_node.cc @@ -19,7 +19,7 @@ #include <ost/gui/gosty_app.hh> #include <ost/mol/query_view_wrapper.hh> - +#include <ost/gui/scene_win/scene_win_model.hh> #include <ost/gfx/scene.hh> #include <ost/gfx/gfx_node.hh> diff --git a/modules/gui/src/scene_win/custom_part_node.cc b/modules/gui/src/scene_win/custom_part_node.cc index 18c9d9972f9646ef64d93b498a7316622eddcc55..e18e6d62c9cc898bda2713a7eadeba9c2e40de13 100644 --- a/modules/gui/src/scene_win/custom_part_node.cc +++ b/modules/gui/src/scene_win/custom_part_node.cc @@ -20,7 +20,7 @@ #include "custom_part_node.hh" #include "entity_part_node.hh" - +#include <ost/gui/scene_win/scene_win_model.hh> #include <ost/gfx/entity.hh> #include <ost/gfx/gfx_node.hh> diff --git a/modules/gui/src/scene_win/entity_node.cc b/modules/gui/src/scene_win/entity_node.cc index 3aa51c81ce37a0f9acdeebd6033d4573b008ee73..4f49dcc96e676a8df67f73179c266f2e029649bd 100644 --- a/modules/gui/src/scene_win/entity_node.cc +++ b/modules/gui/src/scene_win/entity_node.cc @@ -25,7 +25,7 @@ #include <ost/mol/view_type_fw.hh> #include <ost/gui/scene_win/scene_win.hh> - +#include <ost/gui/scene_win/scene_win_model.hh> #include "current_selection_node.hh" #include "entity_part_node.hh" #include "label_node.hh" @@ -43,7 +43,6 @@ EntityNode::EntityNode(gfx::EntityP& entity, SceneNode* parent): GfxSceneNode(entity,parent),custom_view_(NULL){ SceneWinModel* model = GostyApp::Instance()->GetSceneWin()->GetModel(); model->AddNode(parent, this); - new RenderModesNode(entity, this); SceneNode* chain_node = new LabelNode("Chains",this); diff --git a/modules/gui/src/scene_win/entity_part_node.cc b/modules/gui/src/scene_win/entity_part_node.cc index da8867d8bb6e8c5c03f93d7318de63ee6ef81762..bc1fb5a9f3f698ffa94d1c93b2569d7a1ac52f8b 100644 --- a/modules/gui/src/scene_win/entity_part_node.cc +++ b/modules/gui/src/scene_win/entity_part_node.cc @@ -18,14 +18,19 @@ //------------------------------------------------------------------------------ #include "entity_part_node.hh" - +#include <ost/gui/scene_win/scene_win_model.hh> #include <ost/gfx/entity.hh> #include <ost/gfx/gfx_node.hh> #include <QFont> namespace ost { namespace gui { -EntityPartNode::EntityPartNode(QString name, gfx::EntityP entity, mol::QueryViewWrapper part, SceneNode* parent):SceneNode(parent),name_(name),entity_(entity),query_view_(part),visible_(true){ +EntityPartNode::EntityPartNode(QString name, gfx::EntityP entity, + mol::QueryViewWrapper part, + SceneNode* parent): + SceneNode(parent),name_(name),entity_(entity), + query_view_(part),visible_(true) +{ } QVariant EntityPartNode::GetData(int column, int role){ diff --git a/modules/gui/src/scene_win/gfx_scene_node.cc b/modules/gui/src/scene_win/gfx_scene_node.cc index 191007aee833f93a9f4e36b2c2e91a39df4eb4b4..048cee4467023d093c54eda1301d345c26bfbb79 100644 --- a/modules/gui/src/scene_win/gfx_scene_node.cc +++ b/modules/gui/src/scene_win/gfx_scene_node.cc @@ -18,7 +18,7 @@ //------------------------------------------------------------------------------ #include "gfx_scene_node.hh" - +#include <ost/gui/scene_win/scene_win_model.hh> #include <ost/gfx/scene.hh> #include <ost/gfx/gfx_node.hh> diff --git a/modules/gui/src/scene_win/label_node.cc b/modules/gui/src/scene_win/label_node.cc index 8a01e6aec1a27ae35b59a1b3cf0c2f98e3d2fcf1..f6d2d72f549b124ca55395fbbe0f97489334ea4a 100644 --- a/modules/gui/src/scene_win/label_node.cc +++ b/modules/gui/src/scene_win/label_node.cc @@ -21,7 +21,7 @@ #include <ost/gfx/entity.hh> #include <ost/gfx/gfx_node.hh> - +#include <ost/gui/scene_win/scene_win_model.hh> #include <QFont> namespace ost { namespace gui { diff --git a/modules/gui/src/scene_win/render_mode_node.cc b/modules/gui/src/scene_win/render_mode_node.cc index 88e67dea8d5990dae5ffe25a885805df462a8ca2..de6bc6fe609a66cd302f7394e3179c72c97151a9 100644 --- a/modules/gui/src/scene_win/render_mode_node.cc +++ b/modules/gui/src/scene_win/render_mode_node.cc @@ -18,7 +18,7 @@ //------------------------------------------------------------------------------ #include <ost/mol/query_view_wrapper.hh> - +#include <ost/gui/scene_win/scene_win_model.hh> #include "render_mode_node.hh" #include <QFont> diff --git a/modules/gui/src/scene_win/render_modes_node.cc b/modules/gui/src/scene_win/render_modes_node.cc index a343490b894a21123cd97e353433db66dee27562..611cc3561e1ceb55d6bfc24757be9ded52279542 100644 --- a/modules/gui/src/scene_win/render_modes_node.cc +++ b/modules/gui/src/scene_win/render_modes_node.cc @@ -24,7 +24,7 @@ #include <ost/gfx/gfx_node.hh> #include <ost/gui/scene_win/scene_win.hh> - +#include <ost/gui/scene_win/scene_win_model.hh> #include "render_modes_node.hh" #include "render_mode_node.hh" #include <QFont> diff --git a/modules/gui/src/scene_win/scene_win.cc b/modules/gui/src/scene_win/scene_win.cc index ba685c3f62a4d58a6babb74dd65c3c8942428806..e398f96783c5a32d360a2207acf167ea38bf9162 100644 --- a/modules/gui/src/scene_win/scene_win.cc +++ b/modules/gui/src/scene_win/scene_win.cc @@ -23,7 +23,8 @@ #include <ost/gui/gosty_app.hh> #include <ost/gui/widget_registry.hh> #include <ost/gui/scene_selection.hh> - +#include <ost/gui/scene_win/scene_win_model.hh> +#include <ost/gui/scene_win/context_menu.hh> #include "scene_win.hh" #include <QVBoxLayout> diff --git a/modules/gui/src/scene_win/scene_win.hh b/modules/gui/src/scene_win/scene_win.hh index 612198db622f03e3e82bb138eb3ce9d2b85dc164..c0f16a5dc622b575586718aafa3982492e98853a 100644 --- a/modules/gui/src/scene_win/scene_win.hh +++ b/modules/gui/src/scene_win/scene_win.hh @@ -23,20 +23,24 @@ #include <ost/mol/query_view_wrapper.hh> #include <ost/gfx/gfx_node_fw.hh> +#include <ost/gfx/entity.hh> #include <ost/gui/module_config.hh> #include <ost/gui/widget.hh> -#include <ost/gui/scene_win/scene_win_model.hh> -#include <ost/gui/scene_win/context_menu.hh> #include <QTreeView> #include <QItemSelection> + + /* Authors: Marco Biasini, Ansgar Philippsen, Stefan Scheuber */ namespace ost { namespace gui { +class SceneWinModel; +class ContextMenu; + // the display window for all graphical objects class DLLEXPORT_OST_GUI SceneWin: public Widget { diff --git a/modules/gui/src/scene_win/scene_win_model.cc b/modules/gui/src/scene_win/scene_win_model.cc index 9e7542b0815c2a73267820ad1fa1b1991cf8cce9..6c833ba48c94ac4afa6a4ad6e1c61d8d7322f24c 100644 --- a/modules/gui/src/scene_win/scene_win_model.cc +++ b/modules/gui/src/scene_win/scene_win_model.cc @@ -35,6 +35,7 @@ #include <QSize> #include <QFont> +#include <QDebug> namespace ost { namespace gui { @@ -105,19 +106,22 @@ gfx::EntityP SceneWinModel::GetEntityOfViews(QModelIndexList indexes){ return entity; } -void SceneWinModel::Update(){ +void SceneWinModel::Update() +{ emit this->dataChanged(QModelIndex(),QModelIndex()); } -QModelIndex SceneWinModel::index(int row, int col, const QModelIndex& parent) const +QModelIndex SceneWinModel::index(int row, int col, + const QModelIndex& parent) const { SceneNode* parent_node = GetItem(parent); SceneNode* child_node = parent_node->GetChild(row); - if (child_node) - return createIndex(row, col, child_node); - else - return QModelIndex(); + if (child_node) { + return createIndex(row, col, child_node); + } else { + return QModelIndex(); + } } QModelIndex SceneWinModel::parent(const QModelIndex& index) const @@ -231,24 +235,36 @@ QMimeData* SceneWinModel::mimeData(const QModelIndexList &indexes) const void SceneWinModel::NodeAdded(const gfx::GfxNodeP& node) { gfx::EntityP e=boost::dynamic_pointer_cast<gfx::Entity>(node); - if(e){ - new EntityNode(e,scene_node_); + SceneNode* parent_node=this->FindGfxNode(node->GetParent()); + if (parent_node==NULL) { + parent_node=scene_node_; + } + if (e) { + EntityNode* ent_node=new EntityNode(e,parent_node); + node_map_[node.get()]=ent_node; } else{ - SceneNode* scene_node = new GfxSceneNode(node, scene_node_); - this->AddNode(scene_node_,scene_node); + SceneNode* scene_node = new GfxSceneNode(node, parent_node); + node_map_[node.get()]=scene_node; + this->AddNode(parent_node, scene_node); + for (gfx::GfxNodeVector::const_iterator i=node->GetChildren().begin(), + e=node->GetChildren().end(); i!=e; ++i) { + this->NodeAdded(*i); + } } } void SceneWinModel::NodeRemoved(const gfx::GfxNodeP& node) { SceneNode* scene_node = this->FindGfxNode(node); - if(scene_node->GetParent()){ + if(scene_node && scene_node->GetParent()){ + node_map_.remove(node.get()); this->RemoveNode(scene_node); } } -void SceneWinModel::SelectionChanged(const gfx::GfxObjP& obj, const mol::EntityView& sel) +void SceneWinModel::SelectionChanged(const gfx::GfxObjP& obj, + const mol::EntityView& sel) { } @@ -268,8 +284,9 @@ SceneNode* SceneWinModel::GetItem(const QModelIndex &index) const return root_node_; } -bool SceneWinModel::AddNode(SceneNode* parent, SceneNode* child){ - QModelIndex parent_index = GetIndexOf(parent); +bool SceneWinModel::AddNode(SceneNode* parent, SceneNode* child) +{ + QModelIndex parent_index=this->GetIndexOf(parent); if(parent_index.isValid()){ int row = parent->GetChildCount(); this->beginInsertRows(parent_index,row,row); @@ -280,11 +297,12 @@ bool SceneWinModel::AddNode(SceneNode* parent, SceneNode* child){ return false; } -bool SceneWinModel::RemoveNode(SceneNode* node){ - QModelIndex index = GetIndexOf(node); - SceneNode* parent = node->GetParent(); +bool SceneWinModel::RemoveNode(SceneNode* node) +{ + QModelIndex index=this->GetIndexOf(node); + SceneNode* parent=node->GetParent(); if(parent && index.isValid()){ - QModelIndex parent_index = GetIndexOf(parent); + QModelIndex parent_index =this->GetIndexOf(parent); int row = node->GetRow(); this->beginRemoveRows(parent_index,row,row); parent->RemoveChild(node); @@ -295,26 +313,45 @@ bool SceneWinModel::RemoveNode(SceneNode* node){ } -void SceneWinModel::AttachRenderModeObserver(RenderModesNode* node){ +void SceneWinModel::AttachRenderModeObserver(RenderModesNode* node) +{ render_observers_.insert(node->GetGfxNode(),node); } -void SceneWinModel::DetachRenderModeObserver(RenderModesNode* node){ +void SceneWinModel::DetachRenderModeObserver(RenderModesNode* node) +{ if(render_observers_.contains(node->GetGfxNode())){ render_observers_.remove(node->GetGfxNode()); } } -QModelIndex SceneWinModel::GetIndexOf(SceneNode* node, int column){ - return GetIndex(node,index(0,0,QModelIndex()),column); +QModelIndex SceneWinModel::GetIndexOf(SceneNode* node, int column) +{ + std::vector<SceneNode*> trace; + SceneNode* parent=node->GetParent(); + while (parent) { + trace.push_back(parent); + parent=parent->GetParent(); + + } + if (!trace.empty()) { + trace.pop_back(); + } + QModelIndex parent_index=this->index(0, 0, QModelIndex()); + for (std::vector<SceneNode*>::reverse_iterator i=trace.rbegin(), + e=trace.rend(); i!=e; ++i) { + SceneNode* cur=*i; + parent_index=this->GetIndex(cur, parent_index, 0); + } + return this->GetIndex(node, parent_index, column); } -QModelIndex SceneWinModel::GetIndex(SceneNode* node, QModelIndex parent, int column){ +QModelIndex SceneWinModel::GetIndex(SceneNode* node, QModelIndex parent, + int column) { if(parent.isValid()){ SceneNode* parent_node =reinterpret_cast<SceneNode*>(parent.internalPointer()); - if(parent_node == node)return parent; - int i=parent_node->GetChildCount()-1; - while(i>=0){ + if (parent_node == node) return parent; + for (int i=parent_node->GetChildCount()-1; i>=0; --i) { SceneNode* child = parent_node->GetChild(i); if(child == node){ if(column<child->GetColumnCount()) @@ -326,24 +363,18 @@ QModelIndex SceneWinModel::GetIndex(SceneNode* node, QModelIndex parent, int col if (found.isValid()) { return found; } - i--; } } return QModelIndex(); } -SceneNode* SceneWinModel::FindGfxNode(gfx::GfxNodeP node) const{ - int i=0; - while(i<scene_node_->GetChildCount()){ - GfxSceneNode* gfx_scene_node = qobject_cast<GfxSceneNode*>(scene_node_->GetChild(i)); - if(gfx_scene_node && node==gfx_scene_node->GetGfxNode()){ - return gfx_scene_node; - } - else{ - i++; - } +SceneNode* SceneWinModel::FindGfxNode(gfx::GfxNodeP node) +{ + QMap<gfx::GfxNode*, SceneNode*>::iterator i=node_map_.find(node.get()); + if (i!=node_map_.end()) { + return i.value(); } - return root_node_; + return NULL; } }} // ns diff --git a/modules/gui/src/scene_win/scene_win_model.hh b/modules/gui/src/scene_win/scene_win_model.hh index 060b148816aaadb7b9734b8a3333589f97788d17..fbcee3d4bf777f95bd606b4f5be3a9ef5b2c9268 100644 --- a/modules/gui/src/scene_win/scene_win_model.hh +++ b/modules/gui/src/scene_win/scene_win_model.hh @@ -59,7 +59,7 @@ public: SceneNode* GetItem(const QModelIndex &index) const; - SceneNode* FindGfxNode(gfx::GfxNodeP node) const; + SceneNode* FindGfxNode(gfx::GfxNodeP node); bool AddNode(SceneNode* parent, SceneNode* child); @@ -107,6 +107,7 @@ private: SceneNode* scene_node_; QMap<gfx::GfxNodeP, RenderModesNode*> render_observers_; + QMap<gfx::GfxNode*, SceneNode*> node_map_; }; }} diff --git a/modules/gui/src/sequence_viewer/sequence_viewer.cc b/modules/gui/src/sequence_viewer/sequence_viewer.cc index 888a8759711f5972bc0578b0bd1ec01c09720c22..82f3892ba8ecf7ba204d4083905481d623962ee7 100644 --- a/modules/gui/src/sequence_viewer/sequence_viewer.cc +++ b/modules/gui/src/sequence_viewer/sequence_viewer.cc @@ -67,13 +67,21 @@ public: OST_REGISTER_WIDGET(SequenceViewer, SequenceViewerFactory); +struct NodeParentPair { + NodeParentPair(gfx::GfxNodeP n, gfx::GfxNodeP p): node(n), parent(p) {} + + gfx::GfxNodeP node; + gfx::GfxNodeP parent; +}; + struct GetNodesVisitor: public gfx::GfxNodeVisitor { + GetNodesVisitor(): nodes_() {} virtual void VisitObject(gfx::GfxObj* o, const Stack& st) { - nodes_.push_back(o->shared_from_this()); + nodes_.push_back(o->shared_from_this()); } - gfx::NodePtrList nodes_; - gfx::NodePtrList GetNodes(){return nodes_;} + gfx::GfxNodeVector nodes_; + gfx::GfxNodeVector GetNodes() {return nodes_; } }; SequenceViewer::SequenceViewer(bool stand_alone, bool observe_scene, @@ -101,7 +109,7 @@ SequenceViewer::SequenceViewer(bool stand_alone, bool observe_scene, gfx::GfxNodeP root_node = gfx::Scene::Instance().GetRootNode(); GetNodesVisitor gnv; gfx::Scene::Instance().Apply(gnv); - gfx::NodePtrList list = gnv.GetNodes(); + gfx::GfxNodeVector list=gnv.GetNodes(); for(unsigned int i=0; i<list.size();i++){ this->NodeAdded(list[i]); }