Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve 'u' key in PCLVisualizer: search in shapes LUT too #1241

Merged
merged 2 commits into from
Jul 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions visualization/include/pcl/visualization/interactor_style.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ namespace pcl

/** \brief Empty constructor. */
PCLVisualizerInteractorStyle () :
init_ (), rens_ (), actors_ (), win_height_ (), win_width_ (), win_pos_x_ (), win_pos_y_ (),
max_win_height_ (), max_win_width_ (), grid_enabled_ (), grid_actor_ (), lut_enabled_ (),
init_ (), rens_ (), cloud_actors_ (), shape_actors_ (), win_height_ (), win_width_ (), win_pos_x_ (), win_pos_y_ (),
max_win_height_ (), max_win_width_ (), use_vbos_ (false), grid_enabled_ (), grid_actor_ (), lut_enabled_ (),
lut_actor_ (), snapshot_writer_ (), wif_ (), mouse_signal_ (), keyboard_signal_ (),
point_picking_signal_ (), area_picking_signal_ (), stereo_anaglyph_mask_default_ (),
mouse_callback_ (), modifier_ (), camera_file_ (), camera_ (), camera_saved_ (), win_ ()
mouse_callback_ (), modifier_ (), camera_file_ (), camera_ (), camera_saved_ (), win_ (), lut_actor_id_ ("")
{}

/** \brief Empty destructor */
Expand All @@ -131,15 +131,25 @@ namespace pcl
virtual void
Initialize ();

/** \brief Pass a pointer to the actor map
/** \brief Pass a pointer to the cloud actor map
* \param[in] actors the actor map that will be used with this style
*/
inline void
setCloudActorMap (const CloudActorMapPtr &actors) { cloud_actors_ = actors; }

/** \brief Pass a pointer to the shape actor map
* \param[in] actors the actor map that will be used with this style
*/
inline void
setCloudActorMap (const CloudActorMapPtr &actors) { actors_ = actors; }
setShapeActorMap (const ShapeActorMapPtr &actors) { shape_actors_ = actors; }

/** \brief Get the cloud actor map pointer. */
inline CloudActorMapPtr
getCloudActorMap () { return (actors_); }
getCloudActorMap () { return (cloud_actors_); }

/** \brief Get the cloud actor map pointer. */
inline ShapeActorMapPtr
getShapeActorMap () { return (shape_actors_); }

/** \brief Pass a set of renderers to the interactor style.
* \param[in] rens the vtkRendererCollection to use
Expand Down Expand Up @@ -257,8 +267,11 @@ namespace pcl
/** \brief Collection of vtkRenderers stored internally. */
vtkSmartPointer<vtkRendererCollection> rens_;

/** \brief Actor map stored internally. */
CloudActorMapPtr actors_;
/** \brief Cloud actor map stored internally. */
CloudActorMapPtr cloud_actors_;

/** \brief Shape map stored internally. */
ShapeActorMapPtr shape_actors_;

/** \brief The current window width/height. */
int win_height_, win_width_;
Expand Down Expand Up @@ -374,6 +387,18 @@ namespace pcl

friend class PointPickingCallback;
friend class PCLVisualizer;

private:
/** \brief ID used to fetch/display the look up table on the visualizer
* It should be set by PCLVisualizer \ref setLookUpTableID
* @note If empty, a random actor added to the interactor will be used */
std::string lut_actor_id_;

/** \brief Add/remove the look up table displayed when 'u' is pressed, can also be used to update the current LUT displayed
* \ref lut_actor_id_ is used (if not empty) to chose which cloud/shape actor LUT will be updated (depending on what is available)
* If \ref lut_actor_id_ is empty the first actor with LUT support found will be used. */
void
updateLookUpTableDisplay (bool add_lut = false);
};

/** \brief PCL histogram visualizer interactory style class.
Expand Down
18 changes: 6 additions & 12 deletions visualization/include/pcl/visualization/pcl_visualizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1403,18 +1403,6 @@ namespace pcl
const std::string &id = "PolyData",
int viewport = 0);

/** \brief Add a vtkPolyDataMapper as a mesh
* \param[in] polydatamapper vtkPolyDataMapper
* \param[in] id the model id/name (default: "PolyDataMapper")
* \param[in] viewport (optional) the id of the new viewport (default: 0)
* \return True if successful, false otherwise
* \note This allows to display a colored mesh, also see \ref PCL_VISUALIZER_LUT.
*/
bool
addModelFromPolyData (vtkSmartPointer<vtkPolyDataMapper> polydatamapper,
const std::string & id = "PolyDataMapper",
int viewport = 0);

/** \brief Add a PLYmodel as a mesh
* \param[in] filename of the ply file
* \param[in] id the model id/name (default: "PLYModel")
Expand Down Expand Up @@ -1872,6 +1860,12 @@ namespace pcl
void
setUseVbos (bool use_vbos);

/** \brief Set the ID of a cloud or shape to be used for LUT display
* \param[in] id The id of the cloud/shape look up table to be displayed
* The look up table is displayed by pressing 'u' in the PCLVisualizer */
void
setLookUpTableID (const std::string id);

/** \brief Create the internal Interactor object. */
void
createInteractor ();
Expand Down
169 changes: 139 additions & 30 deletions visualization/src/interactor_style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
// Geometry ?
if (keymod)
{
for (it = actors_->begin (); it != actors_->end (); ++it)
for (it = cloud_actors_->begin (); it != cloud_actors_->end (); ++it)
{
CloudActor *act = &(*it).second;
if (index >= static_cast<int> (act->geometry_handlers.size ()))
Expand Down Expand Up @@ -683,7 +683,7 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
}
else
{
for (it = actors_->begin (); it != actors_->end (); ++it)
for (it = cloud_actors_->begin (); it != cloud_actors_->end (); ++it)
{
CloudActor *act = &(*it).second;
// Check for out of bounds
Expand Down Expand Up @@ -786,7 +786,7 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
case 'l': case 'L':
{
// Iterate over the entire actors list and extract the geomotry/color handlers list
for (CloudActorMap::iterator it = actors_->begin (); it != actors_->end (); ++it)
for (CloudActorMap::iterator it = cloud_actors_->begin (); it != cloud_actors_->end (); ++it)
{
std::list<std::string> geometry_handlers_list, color_handlers_list;
CloudActor *act = &(*it).second;
Expand Down Expand Up @@ -1057,27 +1057,7 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
// Display a LUT actor on screen
case 'u': case 'U':
{
CloudActorMap::iterator it;
for (it = actors_->begin (); it != actors_->end (); ++it)
{
CloudActor *act = &(*it).second;

vtkScalarsToColors* lut = act->actor->GetMapper ()->GetLookupTable ();
lut_actor_->SetLookupTable (lut);
lut_actor_->Modified ();
}
if (!lut_enabled_)
{
CurrentRenderer->AddActor (lut_actor_);
lut_actor_->SetVisibility (true);
lut_enabled_ = true;
}
else
{
CurrentRenderer->RemoveActor (lut_actor_);
lut_enabled_ = false;
}
CurrentRenderer->Render ();
updateLookUpTableDisplay (true);
break;
}

Expand All @@ -1098,13 +1078,13 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()

vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera ();

static CloudActorMap::iterator it = actors_->begin ();
static CloudActorMap::iterator it = cloud_actors_->begin ();
// it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
bool found_transformation = false;
for (unsigned idx = 0; idx < actors_->size (); ++idx, ++it)
for (unsigned idx = 0; idx < cloud_actors_->size (); ++idx, ++it)
{
if (it == actors_->end ())
it = actors_->begin ();
if (it == cloud_actors_->end ())
it = cloud_actors_->begin ();

const CloudActor& actor = it->second;
if (actor.viewpoint_transformation_.GetPointer ())
Expand Down Expand Up @@ -1138,10 +1118,10 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
}

// go to the next actor for the next key-press event.
if (it != actors_->end ())
if (it != cloud_actors_->end ())
++it;
else
it = actors_->begin ();
it = cloud_actors_->begin ();

CurrentRenderer->SetActiveCamera (cam);
CurrentRenderer->ResetCameraClippingRange ();
Expand Down Expand Up @@ -1187,6 +1167,135 @@ pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
Interactor->Render ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
// Update the look up table displayed when 'u' is pressed
void
pcl::visualization::PCLVisualizerInteractorStyle::updateLookUpTableDisplay (bool add_lut)
{
CloudActorMap::iterator am_it;
ShapeActorMap::iterator sm_it;
bool actor_found = false;

if (lut_actor_id_ != "") // Search if provided actor id is in CloudActorMap or ShapeActorMap
{
am_it = cloud_actors_->find (lut_actor_id_);
if (am_it == cloud_actors_->end ())
{
sm_it = shape_actors_->find (lut_actor_id_);
if (sm_it == shape_actors_->end ())
{
PCL_WARN ("[updateLookUpTableDisplay] Could not find any actor with id <%s>!\n", lut_actor_id_.c_str ());
if (lut_enabled_)
{ // Remove LUT and exit
CurrentRenderer->RemoveActor (lut_actor_);
lut_enabled_ = false;
}
return;
}

// ShapeActor found
vtkSmartPointer<vtkProp> *act = & (*sm_it).second;
vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast (*act);
if (!actor || !actor->GetMapper ()->GetInput ()->GetPointData ()->GetScalars ())
{
PCL_WARN ("[updateLookUpTableDisplay] id <%s> does not hold any color information!\n", lut_actor_id_.c_str ());
if (lut_enabled_)
{ // Remove LUT and exit
CurrentRenderer->RemoveActor (lut_actor_);
lut_enabled_ = false;
}
return;
}

lut_actor_->SetLookupTable (actor->GetMapper ()->GetLookupTable ());
lut_actor_->Modified ();
actor_found = true;
}
else
{
// CloudActor
CloudActor *act = & (*am_it).second;
if (!act->actor->GetMapper ()->GetLookupTable () && !act->actor->GetMapper ()->GetInput ()->GetPointData ()->GetScalars ())
{
PCL_WARN ("[updateLookUpTableDisplay] id <%s> does not hold any color information!\n", lut_actor_id_.c_str ());
if (lut_enabled_)
{ // Remove LUT and exit
CurrentRenderer->RemoveActor (lut_actor_);
lut_enabled_ = false;
}
return;
}

vtkScalarsToColors* lut = act->actor->GetMapper ()->GetLookupTable ();
lut_actor_->SetLookupTable (lut);
lut_actor_->Modified ();
actor_found = true;
}
}
else // lut_actor_id_ == "", the user did not specify which cloud/shape LUT should be displayed
// Circling through all clouds/shapes and displaying first LUT found
{
for (am_it = cloud_actors_->begin (); am_it != cloud_actors_->end (); ++am_it)
{
CloudActor *act = & (*am_it).second;
if (!act->actor->GetMapper ()->GetLookupTable ())
continue;

if (!act->actor->GetMapper ()->GetInput ()->GetPointData ()->GetScalars ())
continue;

vtkScalarsToColors* lut = act->actor->GetMapper ()->GetLookupTable ();
lut_actor_->SetLookupTable (lut);
lut_actor_->Modified ();
actor_found = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should break here, otherwise search is continued even when a suitable actor is found.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to display the last actor found based on the principle that the last actor has many chances to be at the "end" of the unordered_map but after a short test it's not true.

So you are right, let's break the search and display the first actor with LUT support found.

break;
}

if (!actor_found)
{
for (sm_it = shape_actors_->begin (); sm_it != shape_actors_->end (); ++sm_it)
{
vtkSmartPointer<vtkProp> *act = & (*sm_it).second;
vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast (*act);
if (!actor)
continue;

if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetScalars ()) // Check if actor has scalars
continue;
lut_actor_->SetLookupTable (actor->GetMapper ()->GetLookupTable ());
lut_actor_->Modified ();
actor_found = true;
break;
}
}
}

if (!actor_found)
PCL_WARN ("[updateLookUpTableDisplay] No actor was found with LUT information!\n");

if (!actor_found || (lut_enabled_ && add_lut)) // Remove actor
{
CurrentRenderer->RemoveActor (lut_actor_);
lut_enabled_ = false;
}
else if (!lut_enabled_ && add_lut) // Add actor
{
CurrentRenderer->AddActor (lut_actor_);
lut_actor_->SetVisibility (true);
lut_enabled_ = true;
}
else if (lut_enabled_) // Update actor (if displayed)
{
CurrentRenderer->RemoveActor (lut_actor_);
CurrentRenderer->AddActor (lut_actor_);
}
else
return;

CurrentRenderer->Render ();
return;
}

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::visualization::PCLVisualizerInteractorStyle::OnKeyUp ()
Expand Down
Loading