diff --git a/modules/gfx/pymod/export_map.cc b/modules/gfx/pymod/export_map.cc index cd88c771b87675032b12d8e730b00db5938230d1..966ee0d8cab9ebe76d372b4feee27bf3181478dc 100644 --- a/modules/gfx/pymod/export_map.cc +++ b/modules/gfx/pymod/export_map.cc @@ -50,6 +50,12 @@ void ms_color_by_04(MapSlab *s, const Color& c1, const Color& c2) void export_Map() { + + enum_<MapIsoType>("MapIsoType") + .value("ORIGINAL_MAP", ORIGINAL_MAP) + .value("DOWNSAMPLED_MAP", DOWNSAMPLED_MAP) + ; + class_<MapIso, bases<GfxObj>, boost::shared_ptr<MapIso>, boost::noncopyable>("MapIso", init<const String&, const ::img::MapHandle&, float, optional<uint> >()) .def("SetLevel",&MapIso::SetLevel) @@ -57,6 +63,13 @@ void export_Map() .def("GetMean", &MapIso::GetMean) .def("GetMap", &MapIso::GetMap,return_value_policy<reference_existing_object>()) .def("GetOriginalMap", &MapIso::GetOriginalMap,return_value_policy<reference_existing_object>()) + .def("GetDownsampledMap", &MapIso::GetDownsampledMap,return_value_policy<reference_existing_object>()) + .def("ShowDownsampledMap", &MapIso::ShowDownsampledMap) + .def("ShowOriginalMap", &MapIso::ShowOriginalMap) + .def("IsDownsampledMapAvailable", &MapIso::IsDownsampledMapAvailable) + .def("GetShownMapType", &MapIso::GetShownMapType) + .def("MakeOctreeDirty", &MapIso::MakeOctreeDirty) + .def("IsOctreeDirty", &MapIso::IsOctreeDirty) .def("Rebuild", &MapIso::Rebuild) .def("SetNSF",&MapIso::SetNSF) .def("SetColor", &MapIso::SetColor) diff --git a/modules/gfx/src/impl/map_octree.cc b/modules/gfx/src/impl/map_octree.cc index 33bd93d71ae00f0601015b6ba0571b96621e7a62..cb611fe3e34dd2aecad4b967e003549a2884ec21 100644 --- a/modules/gfx/src/impl/map_octree.cc +++ b/modules/gfx/src/impl/map_octree.cc @@ -25,12 +25,34 @@ namespace ost { namespace gfx { namespace impl { -MapOctree::MapOctree(const img::ImageHandle& map): - map_(map) +MapOctree::MapOctree(const img::ImageHandle& ih): + map_(ih), + built_(false) +{} + +void MapOctree::Initialize() { + built_=false; + levels_.clear(); this->BuildOctree(); } + +void MapOctree::SetNewMap(const img::ImageHandle& ih) +{ + map_=ih; +} + +bool MapOctree::IsMapManageable (const img::ImageHandle ih) +{ + bool manageable = true; + if (ih.GetExtent().GetWidth() > 256 || + ih.GetExtent().GetHeight() > 256 || + ih.GetExtent().GetDepth() > 256 ) manageable=false; + return manageable; +} + + uint32_t MapOctree::GetNumNodesForLevel(uint8_t level) const { img::Size size=map_.GetExtent().GetSize(); @@ -52,7 +74,9 @@ void MapOctree::BuildOctree() assert(p && "Octree only supports real spatial images"); OctreeNode dummy; this->BuildOctreeRec(range_vec, 0, p, map_.GetExtent(), dummy); + built_=true; } + std::pair<float,float> MapOctree::BuildOctreeRec(const OcRangeVector& range_vec, uint16_t level, img::RealSpatialImageState* map, diff --git a/modules/gfx/src/impl/map_octree.hh b/modules/gfx/src/impl/map_octree.hh index 999219e83880049f6df6e0f4c0cde3d9558fd778..4c73f54bd0664d29b0b9c76a63172675fbfa4263 100644 --- a/modules/gfx/src/impl/map_octree.hh +++ b/modules/gfx/src/impl/map_octree.hh @@ -109,8 +109,11 @@ typedef std::vector<OctreeNode> OcNodeEntryList; class DLLEXPORT_OST_GFX MapOctree { public: MapOctree(const img::ImageHandle& map); + void Initialize(); uint32_t GetNumNodesForLevel(uint8_t level) const; - + void SetNewMap(const img::ImageHandle& ih); + static bool IsMapManageable (const img::ImageHandle ih); + /// \brief depth-first visit of octree nodes template <typename F> void VisitDF(F& f) const @@ -216,6 +219,7 @@ private: img::ImageHandle map_; std::vector<OcNodeEntryList> levels_; + bool built_; }; }}} diff --git a/modules/gfx/src/map_iso.cc b/modules/gfx/src/map_iso.cc index 20736f6c981ebafc4426a17ff2253355259e3275..20fb4b8e89a05368327d76999d6b8fbaec220b9b 100644 --- a/modules/gfx/src/map_iso.cc +++ b/modules/gfx/src/map_iso.cc @@ -62,8 +62,8 @@ namespace gfx { MapIso::MapIso(const String& name, const img::MapHandle& mh, float level): GfxObj(name), original_mh_(mh), - downsampled_mh_(MapIso::DownsampleMap(mh)), - mh_(downsampled_mh_), + downsampled_mh_(), + mh_(MapIso::DownsampleMap(mh)), octree_(mh_), level_(level), normals_calculated_(false), @@ -72,6 +72,14 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh, float level): debug_octree_(false), color_(Color::GREY) { + // TODO replace with def mat for this gfx obj type + if (mh.IsFrequency() == true){ + throw Error("Error: Map not in real space. Cannot create of this map"); + } + if (mh_ != original_mh_) { + downsampled_mh_ = mh_; + } + octree_.Initialize(); SetMatAmb(Color(0,0,0)); SetMatDiff(Color(1,1,1)); SetMatSpec(Color(0.1,0.1,0.1)); @@ -87,16 +95,20 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh, float level, uint a): GfxObj(name), original_mh_(mh), - downsampled_mh_(MapIso::DownsampleMap(mh)), - mh_(downsampled_mh_), + downsampled_mh_(), + mh_(MapIso::DownsampleMap(mh)), octree_(mh_), level_(level), normals_calculated_(false), alg_(a), debug_octree_(false), - color_(Color::GREY) + color_(Color::GREY) { // TODO replace with def mat for this gfx obj type + if (downsampled_mh_ == original_mh_) { + mh_ = original_mh_; + downsampled_mh_ = img::ImageHandle(); + } SetMatAmb(Color(0,0,0)); SetMatDiff(Color(1,1,1)); SetMatSpec(Color(0.1,0.1,0.1)); @@ -261,6 +273,17 @@ void MapIso::OnInput(const InputEvent& e) void MapIso::Rebuild() { + if (mh_.IsFrequency() == true){ + throw Error("Error: Map not in real space. Cannot create of this map"); + } + if (octree_.IsMapManageable(mh_) == false) { + throw Error("Error: Map is too big for visualization"); + } + if (IsOctreeDirty()==true) { + octree_.SetNewMap(mh_); + octree_.Initialize(); + dirty_octree_=false; + } va_.Clear(); va_.SetMode(0x2); normals_calculated_=false; @@ -273,7 +296,7 @@ void MapIso::Rebuild() va_.CalcNormals(1.0); va_.DrawNormals(true); #endif - OnRenderModeChange(); + OnRenderModeChange(); } void MapIso::SetLevel(float l) @@ -305,6 +328,11 @@ img::ImageHandle& MapIso::GetOriginalMap() return original_mh_; } +img::ImageHandle& MapIso::GetDownsampledMap() +{ + return downsampled_mh_; +} + float MapIso::GetMean() const { img::alg::Stat stat; @@ -319,11 +347,56 @@ void MapIso::SetNSF(float nsf) Scene::Instance().RequestRedraw(); } +/// \brief sets the donsampled map to active +void MapIso::ShowDownsampledMap() +{ + if (downsampled_mh_.IsValid()) mh_ = downsampled_mh_; + MakeOctreeDirty(); + Rebuild(); + Scene::Instance().RequestRedraw(); +} + +/// \brief sets the original map to active +void MapIso::ShowOriginalMap() +{ + if (original_mh_.IsValid()) mh_ = original_mh_; + MakeOctreeDirty(); + Rebuild(); + Scene::Instance().RequestRedraw(); +} + + +void MapIso::MakeOctreeDirty() +{ + dirty_octree_=true; +} + +MapIsoType MapIso::GetShownMapType() const +{ + MapIsoType ret = ORIGINAL_MAP; + if (mh_ == downsampled_mh_) { + ret = DOWNSAMPLED_MAP; + } + return ret; +} + +bool MapIso::IsOctreeDirty() const +{ + return dirty_octree_; +} + +/// \brief checks if the downsampled map is available +bool MapIso::IsDownsampledMapAvailable() const +{ + return !(downsampled_mh_==img::ImageHandle()); +} + img::ImageHandle MapIso::DownsampleMap(const img::ImageHandle& mh) { uint downsampling_fact = compute_downsampling_fact(mh); img:: ImageHandle ret_mh = mh; if (downsampling_fact != 1) { + LOG_MESSAGE("Downsampling map for more comfortable visualization") img::alg::DiscreteShrink shrink_alg(img::Size(downsampling_fact,downsampling_fact,downsampling_fact)); ret_mh = mh.Apply(shrink_alg); } diff --git a/modules/gfx/src/map_iso.hh b/modules/gfx/src/map_iso.hh index 87eda29a9c988b8d0a0a2623487d5f7476210269..cf2481575de3f0f812230dee42d65f75879949c5 100644 --- a/modules/gfx/src/map_iso.hh +++ b/modules/gfx/src/map_iso.hh @@ -32,6 +32,11 @@ namespace ost { namespace gfx { +enum MapIsoType { + ORIGINAL_MAP, + DOWNSAMPLED_MAP +}; + class MapIso; typedef boost::shared_ptr<MapIso> MapIsoP; @@ -86,6 +91,23 @@ public: // that never goes out of scope, so I get a reference from here img::ImageHandle& GetOriginalMap(); + /// \brief get the map handle of the downsampled map + // The following is a hack. For the DataViewer I need to pass a reference to an ImagHandle + // that never goes out of scope, so I get a reference from here + img::ImageHandle& GetDownsampledMap(); + + /// \brief sets the donsampled map to active + void ShowDownsampledMap(); + + /// \brief sets the original map to active + void ShowOriginalMap(); + + /// \brief checks if the downsampled map is available + bool IsDownsampledMapAvailable() const ; + + /// \brief returns the type of map currently being show + MapIsoType GetShownMapType() const; + /// \brief set color /// /// By default, the color is white. @@ -100,6 +122,13 @@ public: const Color& GetColor() const { return color_; } void SetNSF(float smoothf); void SetDebugOctree(bool flag) { debug_octree_=flag; } + + /// \brief flags the octree to be rebuilt + void MakeOctreeDirty(); + + /// \brief checks is the octree needs to be rebuilt + bool IsOctreeDirty() const; + protected: virtual void CustomPreRenderGL(bool flag); static img::ImageHandle DownsampleMap(const img::ImageHandle& mh); @@ -119,6 +148,7 @@ private: float min_max_; bool debug_octree_; Color color_; + bool dirty_octree_; }; }} diff --git a/modules/gui/src/scene_selection.cc b/modules/gui/src/scene_selection.cc index eb92c848e96f0279c5e526e71887297d16ea9dc5..7beeadc58d7777ca7362424ca03692902d628657 100644 --- a/modules/gui/src/scene_selection.cc +++ b/modules/gui/src/scene_selection.cc @@ -152,6 +152,23 @@ void SceneSelection::ViewDensitySlices() { } } +void SceneSelection::ShowDownsampledMap() +{ + gfx::MapIsoP obj = dyn_cast<gfx::MapIso> (nodes_[0]); + if (obj) { + obj->ShowDownsampledMap(); + } +} + + +void SceneSelection::ShowOriginalMap() +{ + gfx::MapIsoP obj = dyn_cast<gfx::MapIso> (nodes_[0]); + if (obj) { + obj->ShowOriginalMap(); + } +} + #endif // OST_IMG_ENABLED void SceneSelection::Select() { diff --git a/modules/gui/src/scene_selection.hh b/modules/gui/src/scene_selection.hh index 3b5bebabb3aaaca1bccab963d0bd371cf62c446c..2f39898b7a0c9d640787e8b58fa7516ce1b93b26 100644 --- a/modules/gui/src/scene_selection.hh +++ b/modules/gui/src/scene_selection.hh @@ -60,6 +60,8 @@ public slots: void ShowExclusive(); void HideExclusive(); mol::EntityView GetViewUnion(); + void ShowDownsampledMap(); + void ShowOriginalMap(); private slots: void SetActiveNodes(gfx::NodePtrList nodes, gfx::EntityP entity, mol::QueryViewWrapperList views); diff --git a/modules/gui/src/scene_win/context_menu.cc b/modules/gui/src/scene_win/context_menu.cc index d873c99f5ba58e3ed84404a49e177821bd3ce570..5734b636826ef6a2bbd6e1a2e3c6daaa629f73b3 100644 --- a/modules/gui/src/scene_win/context_menu.cc +++ b/modules/gui/src/scene_win/context_menu.cc @@ -114,6 +114,14 @@ ContextMenu::ContextMenu(QTreeView* view, SceneWinModel* model): action = new QAction("View Density Slices",this); connect(action, SIGNAL(triggered()), SceneSelection::Instance(), SLOT(ViewDensitySlices())); this->AddAction(action, MAP); + + action = new QAction("Show Original Map",this); + connect(action, SIGNAL(triggered()), SceneSelection::Instance(), SLOT(ShowOriginalMap())); + this->AddAction(action, MAP | SINGLE | MAP_DOWNSAMPLED); + + action = new QAction("Show Downsampled Map",this); + connect(action, SIGNAL(triggered()), SceneSelection::Instance(), SLOT(ShowDownsampledMap())); + this->AddAction(action, MAP | SINGLE | MAP_ORIGINAL | MAP_DSAMPLED_AVAIL); #endif // OST_IMG_ENABLED } @@ -142,6 +150,24 @@ void ContextMenu::ShowMenu(const QPoint& pos) if(!dynamic_cast<gfx::GfxObj*> (gfx_node.get())){flags &= ~GFX_OBJECT;} if(!dynamic_cast<gfx::Entity*> (gfx_node.get())){flags &= ~ENTITY;} #if OST_IMG_ENABLED + if(!dynamic_cast<gfx::MapIso*> (gfx_node.get())) + { + flags &= ~MAP; + } else { + gfx::MapIso* mapisop = dynamic_cast<gfx::MapIso*> (gfx_node.get()); + if (mapisop->GetShownMapType() == gfx::ORIGINAL_MAP){ + flags &= ~MAP_DOWNSAMPLED; + } else { + flags &= ~MAP_ORIGINAL; + } + if (mapisop->IsDownsampledMapAvailable() == false){ + flags &= ~MAP_DSAMPLED_AVAIL; + } + } + if(!dynamic_cast<gfx::MapIso*> (gfx_node.get())){ + flags &= ~MAP; + + } if(!dynamic_cast<gfx::MapIso*> (gfx_node.get())){flags &= ~MAP;} #endif // OST_IMG_ENABLED } diff --git a/modules/gui/src/scene_win/context_menu.hh b/modules/gui/src/scene_win/context_menu.hh index bc2f8e9d133215c7c66550e4b68c31e2ad575b77..1a2501da86e6f7fea9cc09b56b0cd00b67a4f893 100644 --- a/modules/gui/src/scene_win/context_menu.hh +++ b/modules/gui/src/scene_win/context_menu.hh @@ -45,7 +45,10 @@ enum ContextActionType SINGLE=0x80, MULTI=0x100 #if OST_IMG_ENABLED - ,MAP=0x200 + ,MAP=0x200, + MAP_ORIGINAL=0x400, + MAP_DOWNSAMPLED=0x800, + MAP_DSAMPLED_AVAIL=0x1000 #endif }; Q_DECLARE_FLAGS(ContextActionTypes, ContextActionType)