Commit d08823e3 authored by Dirk Wilden's avatar Dirk Wilden
Browse files

FloodFill Selection

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@6990 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 819c0283
......@@ -293,6 +293,67 @@ void SelectionPlugin::componentSelection(QMouseEvent* _event) {
}
//***********************************************************************************
/** \brief FloodFill an area starting from the selected element
*
* @param _event mouse event that occurred
*/
void SelectionPlugin::floodFillSelection(QMouseEvent* _event)
{
if ( _event->type() != QEvent::MouseButtonPress ) return;
if ( _event->button() == Qt::RightButton ) return;
unsigned int node_idx, target_idx;
ACG::Vec3d hit_point;
// pick Anything to find all possible objects
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING,
_event->pos(),node_idx, target_idx, &hit_point))
{
BaseObjectData* object(0);
if(PluginFunctions::getPickedObject(node_idx, object))
{
// OBJECT SELECTION
if (selectionType_ & OBJECT)
return;
maxFloodFillAngle_ = tool_->maxFloodFillAngle->value();
// TRIANGLE MESHES
if (object->dataType() == DATA_TRIANGLE_MESH) {
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point))
if ( PluginFunctions::getPickedObject(node_idx, object) )
if ( object->dataType(DATA_TRIANGLE_MESH) ){
floodFillSelection(PluginFunctions::triMesh(object), target_idx);
emit updatedObject(object->id());
}
// POLY MESHES
}else if (object->dataType() == DATA_POLY_MESH) {
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point))
if ( PluginFunctions::getPickedObject(node_idx, object) )
if ( object->dataType(DATA_POLY_MESH) ) {
floodFillSelection(PluginFunctions::polyMesh(object), target_idx);
emit updatedObject(object->id());
}
}
else{
emit log(LOGERR,tr("floodFillSelection : Unsupported dataType"));
}
}
}
}
//-----------------------------------------------------------------------------
#ifdef ENABLE_POLYLINE_SUPPORT
......
......@@ -48,6 +48,9 @@
#include <MeshTools/MeshNavigationT.hh>
#include <MeshTools/MeshSelectionT.hh>
#include <OpenMesh/Core/Geometry/MathDefs.hh>
#include <math.h>
//***********************************************************************************
......@@ -558,6 +561,71 @@ void SelectionPlugin::componentSelection(MeshT* _mesh, uint _fh) {
//***********************************************************************************
/** \brief Select all primitves of a planar region surrounding the faceHandle
*
* @param _mesh a mesh
* @param _fh handle of the face that was picked
*/
template< class MeshT >
void SelectionPlugin::floodFillSelection(MeshT* _mesh, uint _fh) {
// reset tagged status
typename MeshT::FaceIter f_it, f_end(_mesh->faces_end());
for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it)
_mesh->status(f_it).set_tagged(false);
std::vector<typename MeshT::FaceHandle> face_handles;
typename MeshT::FaceHandle hitFace = typename MeshT::FaceHandle(_fh);
face_handles.reserve(50);
face_handles.push_back( hitFace );
_mesh->status(hitFace).set_tagged(true);
typename MeshT::Point n1 = _mesh->normal( hitFace );
double maxAngle = OpenMesh::deg_to_rad( maxFloodFillAngle_ );
while (!face_handles.empty()) {
typename MeshT::FaceHandle fh = face_handles.back();
face_handles.pop_back();
for (typename MeshT::FaceFaceIter ff_it(*_mesh,fh) ; ff_it ; ++ff_it ) {
// Check if already tagged
if ( _mesh->status(ff_it).tagged() )
continue;
typename MeshT::Point n2 = _mesh->normal( ff_it );
double angle = acos( n1 | n2 );
if ( angle <= maxAngle ){
_mesh->status(ff_it).set_tagged(true);
face_handles.push_back(ff_it.handle());
}
}
}
// now select all tagged primitives
for (f_it=_mesh->faces_begin(); f_it!=f_end; ++f_it)
if (_mesh->status(f_it).tagged()){
if (selectionType_ & VERTEX)
for ( typename MeshT::FaceVertexIter fv_it(*_mesh,f_it) ; fv_it; ++fv_it )
_mesh->status(fv_it).set_selected( !deselection_ );
if (selectionType_ & EDGE)
for ( typename MeshT::FaceEdgeIter fe_it(*_mesh,f_it) ; fe_it; ++fe_it )
_mesh->status(fe_it).set_selected( !deselection_ );
if (selectionType_ & FACE)
_mesh->status(f_it).set_selected( !deselection_ );
}
}
//***********************************************************************************
/** \brief Select all primitves that are projected to the given region
*
* @param _mesh a mesh
......
......@@ -151,6 +151,7 @@ void SelectionPlugin::pluginsInitialized() {
emit addHiddenPickMode(VOLUME_LASSO_SELECTION);
emit addHiddenPickMode(SURFACE_LASSO_SELECTION);
emit addHiddenPickMode(CONNECTED_COMPONENT_SELECTION);
emit addHiddenPickMode(FLOOD_FILL_SELECTION);
emit setPickModeMouseTracking(PAINT_SPHERE_SELECTION, true);
emit setPickModeMouseTracking(LASSO_SELECTION, true);
......@@ -258,7 +259,12 @@ void SelectionPlugin::pluginsInitialized() {
connectedAction_ = new QAction( QIcon(iconPath + "selection_connected.png"),
tr("<B>Connected Component</B><br>Select the connect component to a clicked element."), toolBarActions_ );
connectedAction_->setCheckable( true );
toolBar_->addAction( connectedAction_ );
floodFillAction_ = new QAction( QIcon(iconPath + "selection_floodFill.png"),
tr("<B>Flood Fill</B><br>Select a planar region surrounding the clicked element."), toolBarActions_ );
floodFillAction_->setCheckable( true );
toolBar_->addAction( floodFillAction_ );
connect( toolBarActions_, SIGNAL( triggered(QAction*) ), this, SLOT(toolBarActionClicked(QAction*)) );
connect( toolBarTypes_, SIGNAL( triggered(QAction*) ), this, SLOT(toolBarActionClicked(QAction*)) );
......@@ -477,7 +483,8 @@ void SelectionPlugin::slotMouseEvent( QMouseEvent* _event ) {
if ( PluginFunctions::pickMode() == CLOSEST_BOUNDARY_SELECTION) closestBoundarySelection(_event); else
if ( PluginFunctions::pickMode() == LASSO_SELECTION) handleLassoSelection(_event, false); else
if ( PluginFunctions::pickMode() == VOLUME_LASSO_SELECTION) handleLassoSelection(_event, true); else
if ( PluginFunctions::pickMode() == CONNECTED_COMPONENT_SELECTION) componentSelection(_event);
if ( PluginFunctions::pickMode() == CONNECTED_COMPONENT_SELECTION) componentSelection(_event); else
if ( PluginFunctions::pickMode() == FLOOD_FILL_SELECTION) floodFillSelection(_event);
#ifdef ENABLE_POLYLINE_SUPPORT
else
if ( PluginFunctions::pickMode() == SURFACE_LASSO_SELECTION) surfaceLassoSelection(_event);
......@@ -520,6 +527,7 @@ void SelectionPlugin::slotPickModeChanged( const std::string& _mode) {
lassoAction_->setChecked( _mode == LASSO_SELECTION );
volumeLassoAction_->setChecked( _mode == VOLUME_LASSO_SELECTION );
connectedAction_->setChecked( _mode == CONNECTED_COMPONENT_SELECTION );
floodFillAction_->setChecked( _mode == FLOOD_FILL_SELECTION );
if ( _mode != PAINT_SPHERE_SELECTION && sphere_node_->visible() ){
sphere_node_->hide();
......@@ -610,6 +618,8 @@ void SelectionPlugin::toolBarActionClicked(QAction * _action)
PluginFunctions::pickMode( VOLUME_LASSO_SELECTION );
else if (_action == connectedAction_)
PluginFunctions::pickMode( CONNECTED_COMPONENT_SELECTION );
else if (_action == floodFillAction_)
PluginFunctions::pickMode( FLOOD_FILL_SELECTION );
else if (_action == surfaceLassoAction_){
waitingForPolyLineSelection_ = true;
PluginFunctions::pickMode("PolyLine");
......
......@@ -90,6 +90,7 @@
#define VOLUME_LASSO_SELECTION "Select (Volume Lasso)"
#define SURFACE_LASSO_SELECTION "Select (Surface Lasso)"
#define CONNECTED_COMPONENT_SELECTION "Select (Connected Component)"
#define FLOOD_FILL_SELECTION "Select (Flood Fill)"
enum SelectionPrimitive {
VERTEX = 0x01,
......@@ -194,6 +195,7 @@ class SelectionPlugin : public QObject, BaseInterface , MouseInterface, KeyInter
QAction* volumeLassoAction_;
QAction* surfaceLassoAction_;
QAction* connectedAction_;
QAction* floodFillAction_;
private slots:
/// Switch selection mode dependent which buttons are pressed in the toolbar
......@@ -277,10 +279,17 @@ class SelectionPlugin : public QObject, BaseInterface , MouseInterface, KeyInter
/// Select all primitves of connected component
void componentSelection(QMouseEvent* _event);
/// Select all primitves on a (approx) planar region
void floodFillSelection(QMouseEvent* _event);
/// Select all primitves of connected component
template< class MeshT >
void componentSelection(MeshT* _mesh, uint _fh);
/// Select all primitves of a planar region surrounding the faceHandle
template< class MeshT >
void floodFillSelection(MeshT* _mesh, uint _fh);
/// Handle Mouse move event for lasso selection
void handleLassoSelection(QMouseEvent* _event, bool _volume);
......@@ -635,6 +644,16 @@ class SelectionPlugin : public QObject, BaseInterface , MouseInterface, KeyInter
/** @} */
//===========================================================================
/** @name Variables for FloodFill Selection
* @{ */
//===========================================================================
private:
double maxFloodFillAngle_;
/** @} */
//===========================================================================
/** @name Context Menu
* @{ */
......
......@@ -6,14 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>362</width>
<height>688</height>
<width>420</width>
<height>827</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
......@@ -577,6 +577,62 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Tool Parameters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTabWidget" name="tabWidget">
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Flood Fill</string>
</attribute>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Maximum angle:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="maxFloodFillAngle">
<property name="toolTip">
<string>Maximum angle between faces that get flood filled</string>
</property>
<property name="statusTip">
<string>Maximum angle between faces that get flood filled</string>
</property>
<property name="maximum">
<double>180.000000000000000</double>
</property>
<property name="value">
<double>15.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>88</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment