Commit e09f24b3 authored by Jan Möbius's avatar Jan Möbius
Browse files

Get rid of the twenty region pick functions in the qtbaseviewer.

refs #479



git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14506 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 4236fc2b
......@@ -473,7 +473,7 @@ bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarge
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list)
{
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, 0 , 0);
}
bool scenegraphRegionPick( const unsigned int _examiner,
......@@ -485,7 +485,7 @@ bool scenegraphRegionPick( const unsigned int _examiner,
std::cerr << "Wrong examiner id" << std::endl;
return false;
}
return examiner_widgets_[_examiner]->pick_region( _pickTarget, _region, _list);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, 0, 0);
}
bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarget,
......@@ -493,7 +493,7 @@ bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarge
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<ACG::Vec3d>& _points)
{
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, _points);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, 0, &_points);
}
bool scenegraphRegionPick( const unsigned int _examiner,
......@@ -506,7 +506,7 @@ bool scenegraphRegionPick( const unsigned int _examiner,
std::cerr << "Wrong examiner id" << std::endl;
return false;
}
return examiner_widgets_[_examiner]->pick_region( _pickTarget, _region, _list, _points);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, 0, &_points);
}
bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarget,
......@@ -514,7 +514,7 @@ bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarge
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<float>& _depths)
{
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, _depths);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, &_depths, 0);
}
bool scenegraphRegionPick( const unsigned int _examiner,
......@@ -527,7 +527,7 @@ bool scenegraphRegionPick( const unsigned int _examiner,
std::cerr << "Wrong examiner id" << std::endl;
return false;
}
return examiner_widgets_[_examiner]->pick_region( _pickTarget, _region, _list, _depths);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, &_depths, 0);
}
bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarget,
......@@ -536,7 +536,7 @@ bool scenegraphRegionPick( ACG::SceneGraph::PickTarget _pickTarge
QVector<float>& _depths,
QVector<ACG::Vec3d>& _points)
{
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, _depths, _points);
return examiner_widgets_[activeExaminer_]->pick_region( _pickTarget, _region, _list, &_depths, &_points);
}
bool scenegraphRegionPick( const unsigned int _examiner,
......@@ -550,7 +550,7 @@ bool scenegraphRegionPick( const unsigned int _examiner,
std::cerr << "Wrong examiner id" << std::endl;
return false;
}
return examiner_widgets_[_examiner]->pick_region( _pickTarget, _region, _list, _depths, _points);
return examiner_widgets_[_examiner]->pick_region( _pickTarget, _region, _list, &_depths, &_points);
}
//Warning : Dont use template function as external static pointer for examiner widget is not resolved correctly!!
......
......@@ -717,7 +717,7 @@ private:
/** \brief Handle key events in view mode
*
* This funtion is called by the BaseViewer if a key press event occured in view mode.
* This function is called by the BaseViewer if a key press event occured in view mode.
* This function has to be implemented by every viewer!
*
* @return If the derived class handled the event it has to return true otherwise false
......@@ -790,10 +790,10 @@ private:
*
* @param _pickTarget Select what should be picked: Faces/Vertices/...
* @param _mousePos The position to be used for picking
* @param _nodeIdx If picking is successfull this will contain the id of the scenegraph node picked.
* @param _nodeIdx If picking is successful this will contain the id of the scenegraph node picked.
* @param _targetIdx Special index defined by the picked Node. E.g. Facehandle/VertexHandle/.. for MeshNodes
* @param _hitPointPtr Pointer to 3D point from picking
* @return Successfull?
* @return Successful?
*/
bool pick( ACG::SceneGraph::PickTarget _pickTarget,
const QPoint& _mousePos,
......@@ -801,80 +801,30 @@ private:
unsigned int& _targetIdx,
ACG::Vec3d* _hitPointPtr=0 );
/** Apply pick action. <br>
* Picks all objects in the given Region. Information about the picked primitives is stored in the
* provided list. Resulting values are defined only if \c true
* has been returned!
* <br>
*
* @param _pickTarget Select what should be picked: Faces/Vertices/...
* @param _region Area for picking
* @param _list List of found scenegraph objects (node/target pairs)
* @return Successfull?
*/
bool pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list);
/** Apply pick action. <br>
* Picks all objects in the given Region. Information about the picked primitives is stored in the
* provided list. Resulting values are defined only if \c true
* has been returned!
* <br>
*
* @param _pickTarget Select what should be picked: Faces/Vertices/...
* @param _region Area for picking
* @param _list List of found scenegraph objects (node/target pairs)
* @param _points back projected 3d points
* @return Successful?
*/
bool pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<ACG::Vec3d>& _points);
/** Apply pick action. <br>
* Picks all objects in the given Region. Information about the picked primitives is stored in the
* provided list. Resulting values are defined only if \c true
* has been returned!
* <br>
/** \brief Perform picking action n a whole region.
*
* @param _pickTarget Select what should be picked: Faces/Vertices/...
* @param _region Area for picking
* @param _list List of found scenegraph objects (node/target pairs)
* @param _depths depths [0,1]
* @return Successful?
*/
bool pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<float>& _depths);
/** Apply pick action. <br>
* Apply pick action. <br>
* Picks all objects in the given Region. Information about the picked primitives is stored in the
* provided list. Resulting values are defined only if \c true
* has been returned!
* <br>
* provided list. Resulting values are defined only if \c true has been returned!
*
* @param _pickTarget Select what should be picked: Faces/Vertices/...
* @param _region Area for picking
* @param _list List of found scenegraph objects (node/target pairs)
* @param _depths depths [0,1]
* @param _points back projected 3d points
* @param _depths depths [0,1] (Only provided, if requested)
* @param _points back projected 3d points (Only provided, if requested)
* @return Successful?
*/
bool pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<float>& _depths,
QVector<ACG::Vec3d>& _points);
QVector<float>* _depths = 0,
QVector<ACG::Vec3d>* _points = 0);
/** get the coordinates of the picked point by z-buffer re-projection
* @param _mousePos The position to pick
* @param _hitPoint The point returned by the reprojection
* @return Successfull?
* @return Successful?
*/
bool fast_pick( const QPoint& _mousePos,
ACG::Vec3d& _hitPoint );
......
......@@ -509,7 +509,9 @@ bool glViewer::pickGL( ACG::SceneGraph::PickTarget _pickTarget,
bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list)
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<float>* _depths,
QVector<ACG::Vec3d>* _points)
{
QRect rect = _region.boundingRect();
GLint w = glWidth(),
......@@ -518,7 +520,9 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
b = scene()->height () - scenePos().y() - h,
x = rect.x(),
y = scene()->height () - rect.bottom();
GLubyte* buffer;
GLubyte* buffer = 0;
GLfloat* depths = 0;
if (pickCacheSupported_)
{
......@@ -589,7 +593,7 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
ACG::GLState::enable(GL_LIGHTING);
ACG::GLState::enable(GL_BLEND);
properties_.glState().set_clear_color (clear_color);
properties_.glState().set_clear_color(clear_color);
if (properties_.glState().pick_error ())
{
......@@ -600,148 +604,7 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
buffer = new GLubyte[4 * rect.width() * rect.height()];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels (x, y, rect.width(),
rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer);
QSet<QPair<unsigned int, unsigned int> > found;
for (int y = 0; y < rect.height (); y++)
for (int x = 0; x < rect.width (); x++)
{
if (_region.contains (QPoint (rect.x() + x, rect.y() + y)))
{
int bPos = (((rect.height () - (y + 1)) * rect.width ()) + x) * 4;
if (buffer[bPos + 2] != 0 || buffer[bPos + 1] != 0 || buffer[bPos] != 0 || buffer[bPos + 3] != 0)
{
ACG::Vec4uc rgba;
rgba[0] = buffer[bPos];
rgba[1] = buffer[bPos + 1];
rgba[2] = buffer[bPos + 2];
rgba[3] = buffer[bPos + 3];
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
if (rv.size () < 2)
continue;
found << QPair<unsigned int, unsigned int>(rv[1], rv[0]);
}
}
}
delete[] buffer;
_list = found.toList();
// unbind pick cache
if (pickCache_ && pickCache_->isBound ())
{
pickCache_->release ();
updatePickCache_ = false;
pickCacheTarget_ = _pickTarget;
}
return true;
}
//-----------------------------------------------------------------------------
bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<ACG::Vec3d>& _points)
{
QRect rect = _region.boundingRect();
GLint w = glWidth(),
h = glHeight(),
l = scenePos().x(),
b = scene()->height () - scenePos().y() - h,
x = rect.x(),
y = scene()->height () - rect.bottom();
GLubyte* buffer;
GLfloat* depths;
if (pickCacheSupported_)
{
// delete pick cache if the size changed
if (pickCache_ && pickCache_->size () != QSize (glWidth (), glHeight ()))
{
delete pickCache_;
pickCache_ = NULL;
}
// create a new pick cache frambuffer object
if (!pickCache_)
{
pickCache_ = new QGLFramebufferObject (glWidth (), glHeight (), QGLFramebufferObject::Depth);
if (!pickCache_->isValid ())
{
pickCacheSupported_ = false;
delete pickCache_;
pickCache_ = NULL;
}
}
if (pickCache_)
{
// the viewport for the framebuffer object
l = 0;
b = 0;
x = rect.x() - scenePos().x();
y = glHeight() - (rect.bottom() - scenePos().y());
// we can only pick inside of our window
if (x < 0 || y < 0 || x >= (int)glWidth() || y >= (int)glHeight())
return 0;
pickCache_->bind ();
}
}
const ACG::GLMatrixd& modelview = properties_.glState().modelview();
const ACG::GLMatrixd& projection = properties_.glState().projection();
ACG::Vec4f clear_color = properties_.glState().clear_color();
properties_.glState().set_clear_color (ACG::Vec4f (0.0, 0.0, 0.0, 0.0));
// prepare GL state
makeCurrent();
glViewport (l, b, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixd(projection.get_raw_data());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(modelview.get_raw_data());
ACG::GLState::disable(GL_LIGHTING);
ACG::GLState::disable(GL_BLEND);
ACG::GLState::enable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
properties_.glState().pick_init (true);
// do the picking
ACG::SceneGraph::PickAction action(properties_.glState(), _pickTarget, properties_.drawMode());
ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, action,properties_.glState());
// restore GL state
glMatrixMode( GL_PROJECTION );
glLoadMatrixd(projection.get_raw_data());
glMatrixMode( GL_MODELVIEW );
glLoadMatrixd(modelview.get_raw_data());
ACG::GLState::enable(GL_LIGHTING);
ACG::GLState::enable(GL_BLEND);
properties_.glState().set_clear_color (clear_color);
if (properties_.glState().pick_error ())
{
if (pickCache_ && pickCache_->isBound ())
pickCache_->release ();
return -1;
}
buffer = new GLubyte[4 * rect.width() * rect.height()];
depths = new GLfloat[ rect.width() * rect.height() ];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
......@@ -749,379 +612,40 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
glReadPixels (x, y, rect.width(),
rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glReadPixels (x, y, rect.width(), rect.height(), GL_DEPTH_COMPONENT, GL_FLOAT, depths);
QImage depthmapimage(rect.width(), rect.height(), QImage::Format_Indexed8);
// color map
for ( int i = 0 ; i <= 255 ; i++ )
depthmapimage.setColor( i, qRgb( i, i, i ) );
if (_depths || _points ) {
depths = new GLfloat[ rect.width() * rect.height() ];
glReadPixels (x, y, rect.width(), rect.height(), GL_DEPTH_COMPONENT, GL_FLOAT, depths);
for ( int i = 0 ; i < rect.width() ; i++ )
for ( int j = 0 ; j < rect.height() ; j++ )
{
//std::cerr << "("<<i<<","<<j<<") depth " << depths[j*rect.width()+i] << std::endl;
depthmapimage.setPixel(i,rect.height()-j-1, (unsigned int)(depths[j*rect.width()+i]*255));
}
/* Debug code, writing out the depth image
QImage depthmapimage(rect.width(), rect.height(), QImage::Format_Indexed8);
depthmapimage.save("test.png");
// color map
for ( int i = 0 ; i <= 255 ; i++ )
depthmapimage.setColor( i, qRgb( i, i, i ) );
// needed for consistent ordering (Set->toList undefined order!!)
//QList<QPair<unsigned int, unsigned int> > found;
// 3d position for unproject
ACG::Vec3d pos3d;
for (int y = 0; y < rect.height (); y++)
for (int x = 0; x < rect.width (); x++)
{
if (_region.contains (QPoint (rect.x() + x, rect.y() + y)))
for ( int i = 0 ; i < rect.width() ; i++ )
for ( int j = 0 ; j < rect.height() ; j++ )
{
int bPos = (((rect.height () - (y + 1)) * rect.width ()) + x) * 4;
if (buffer[bPos + 2] != 0 || buffer[bPos + 1] != 0 || buffer[bPos] != 0 || buffer[bPos + 3] != 0)
{
ACG::Vec4uc rgba;
rgba[0] = buffer[bPos];
rgba[1] = buffer[bPos + 1];
rgba[2] = buffer[bPos + 2];
rgba[3] = buffer[bPos + 3];
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
if (rv.size () < 2)
continue;
QPair< unsigned int, unsigned int> curr(rv[1], rv[0]);
// check if already contained
if( !_list.contains( curr))
{
_list << curr;
// unproject depth to real (3D) depth value
pos3d = properties_.glState().unproject(ACG::Vec3d(x+rect.x(),h-(y+rect.y()),depths[(rect.height()-y-1)*rect.width() + x]));
_points << pos3d;
}
}
depthmapimage.setPixel(i,rect.height()-j-1, (unsigned int)(depths[j*rect.width()+i]*255));
}
}
delete[] buffer;
//_list = found.toList();
// unbind pick cache
if (pickCache_ && pickCache_->isBound ())
{
pickCache_->release ();
updatePickCache_ = false;
pickCacheTarget_ = _pickTarget;
depthmapimage.save("test.png");
*/
}
return true;
}
//-----------------------------------------------------------------------------
bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarget,
const QRegion& _region,
QList<QPair<unsigned int, unsigned int> >& _list,
QVector<float>& _depths)
{
QRect rect = _region.boundingRect();
GLint w = glWidth(),
h = glHeight(),
l = scenePos().x(),
b = scene()->height () - scenePos().y() - h,
x = rect.x(),
y = scene()->height () - rect.bottom();
GLubyte* buffer;
GLfloat* depths;
if (pickCacheSupported_)
{
// delete pick cache if the size changed
if (pickCache_ && pickCache_->size () != QSize (glWidth (), glHeight ()))
{
delete pickCache_;
pickCache_ = NULL;
}
// create a new pick cache frambuffer object
if (!pickCache_)
{
pickCache_ = new QGLFramebufferObject (glWidth (), glHeight (), QGLFramebufferObject::Depth);
if (!pickCache_->isValid ())
{
pickCacheSupported_ = false;
delete pickCache_;
pickCache_ = NULL;
}
}
if (pickCache_)
{
// the viewport for the framebuffer object
l = 0;
b = 0;
x = rect.x() - scenePos().x();
y = glHeight() - (rect.bottom() - scenePos().y());
// we can only pick inside of our window
if (x < 0 || y < 0 || x >= (int)glWidth() || y >= (int)glHeight())
return 0;
pickCache_->bind ();
}
}
const ACG::GLMatrixd& modelview = properties_.glState().modelview();
const ACG::GLMatrixd& projection = properties_.glState().projection();
ACG::Vec4f clear_color = properties_.glState().clear_color();
properties_.glState().set_clear_color (ACG::Vec4f (0.0, 0.0, 0.0, 0.0));
// prepare GL state
makeCurrent();
glViewport (l, b, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixd(projection.get_raw_data());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(modelview.get_raw_data());
ACG::GLState::disable(GL_LIGHTING);
ACG::GLState::disable(GL_BLEND);
ACG::GLState::enable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
properties_.glState().pick_init (true);
// do the picking
ACG::SceneGraph::PickAction action(properties_.glState(), _pickTarget, properties_.drawMode());
ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, action,properties_.glState());
// restore GL state
glMatrixMode( GL_PROJECTION );
glLoadMatrixd(projection.get_raw_data());
glMatrixMode( GL_MODELVIEW );
glLoadMatrixd(modelview.get_raw_data());
ACG::GLState::enable(GL_LIGHTING);
ACG::GLState::enable(GL_BLEND);
properties_.glState().set_clear_color (clear_color);
if (properties_.glState().pick_error ())
{
if (pickCache_ && pickCache_->isBound ())
pickCache_->release ();
return -1;
}
buffer = new GLubyte[4 * rect.width() * rect.height()];
depths = new GLfloat[ rect.width() * rect.height() ];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels (x, y, rect.width(),
rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glReadPixels (x, y, rect.width(), rect.height(), GL_DEPTH_COMPONENT, GL_FLOAT, depths);
QImage depthmapimage(rect.width(), rect.height(), QImage::Format_Indexed8);
// color map
for ( int i = 0 ; i <= 255 ; i++ )
depthmapimage.setColor( i, qRgb( i, i, i ) );
for ( int i = 0 ; i < rect.width() ; i++ )
for ( int j = 0 ; j < rect.height() ; j++ )
{
//std::cerr << "("<<i<<","<<j<<") depth " << depths[j*rect.width()+i] << std::endl;
depthmapimage.setPixel(i,rect.height()-j-1, (unsigned int)(depths[j*rect.width()+i]*255));
}
depthmapimage.save("test.png");
//QSet<QPair<unsigned int, unsigned int> > found;
//int setsize = 0;
// Iterate over the bounding rectangle of the region
for (int y = 0; y < rect.height (); y++)
for (int x = 0; x < rect.width (); x++)
{
if (_region.contains (QPoint (rect.x() + x, rect.y() + y)))
{
int bPos = (((rect.height () - (y + 1)) * rect.width ()) + x) * 4;
if (buffer[bPos + 2] != 0 || buffer[bPos + 1] != 0 || buffer[bPos] != 0 || buffer[bPos + 3] != 0)
{
ACG::Vec4uc rgba;
rgba[0] = buffer[bPos];
rgba[1] = buffer[bPos + 1];
rgba[2] = buffer[bPos + 2];
rgba[3] = buffer[bPos + 3];
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
if (rv.size () < 2)
continue;
QPair<unsigned int, unsigned int> curr(rv[1], rv[0]);
//found << QPair<unsigned int, unsigned int>(rv[1], rv[0]);
// added a new (targetidx/nodeidx) pair
//if( setsize != found.size())
if( !_list.contains(curr))
{
//setsize++;
_list << curr;
//_depths << depths[(rect.height()-y-1)*rect.width() + x];