diff --git a/Documentation/doc/scripts/html_output_post_processing.py b/Documentation/doc/scripts/html_output_post_processing.py index f01a02f1eef..44d15aa6d70 100755 --- a/Documentation/doc/scripts/html_output_post_processing.py +++ b/Documentation/doc/scripts/html_output_post_processing.py @@ -254,6 +254,11 @@ removes some unneeded files, and performs minor repair on some glitches.''') resources_absdir=args.resources os.chdir(args.output) + #workaround issue with operator<< in pyquery + all_pages=glob.glob('*/*.html') + for f in all_pages: + re_replace_in_file("operator<<\(\)", "operator<<()", f) + # number figure automagically_number_figures() diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h index bda76bafb05..08f76d4eb0b 100644 --- a/GraphicsView/include/CGAL/Qt/camera.h +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace CGAL{ class QGLViewer; @@ -199,6 +200,7 @@ public: CGAL::QGLViewer's window dimensions when the Camera is attached to a CGAL::QGLViewer. See also QOpenGLWidget::height() */ int screenHeight() const { return screenHeight_; } + qreal devicePixelRatio() const { return devicePixelRatio_; } void getViewport(GLint viewport[4]) const; qreal pixelGLRatio(const Vec &position) const; @@ -279,7 +281,7 @@ public Q_SLOTS: setScreenWidthAndHeight(int(100.0 * aspect), 100); } - void setScreenWidthAndHeight(int width, int height); + void setScreenWidthAndHeight(int width, int height, qreal devicePixelRatio = 1.0); /*! Sets the zNearCoefficient() value. */ void setZNearCoefficient(qreal coef) { zNearCoef_ = coef; @@ -444,6 +446,7 @@ private: // C a m e r a p a r a m e t e r s int screenWidth_, screenHeight_; // size of the window, in pixels + qreal devicePixelRatio_; qreal fieldOfView_; // in radians Vec sceneCenter_; qreal sceneRadius_; // OpenGL units @@ -467,6 +470,36 @@ private: KeyFrameInterpolator *interpolationKfi_; }; +inline void read_pixel(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera, GLenum format, GLenum type, + GLvoid *pixel_data) { + const auto pixel_ratio = camera->devicePixelRatio(); + p->glReadPixels(pixel.x() * pixel_ratio, + (camera->screenHeight() - pixel.y()) * pixel_ratio - 1, 1, 1, + format, type, pixel_data); +} + +inline auto read_pixel_as_float_rgb(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + std::array res; + read_pixel(pixel, p, camera, GL_RGB, GL_FLOAT, res.data()); + return res; +} + +inline auto read_pixel_as_ubyte_rgba(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + std::array res; + read_pixel(pixel, p, camera, GL_RGBA, GL_UNSIGNED_BYTE, res.data()); + return res; +} + +inline float read_depth_under_pixel(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + float depth = 2.0f; + read_pixel(pixel, p, camera, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + return depth; +} + } // namespace qglviewer } //CGAL #endif // QGLVIEWER_CAMERA_H diff --git a/GraphicsView/include/CGAL/Qt/camera_impl.h b/GraphicsView/include/CGAL/Qt/camera_impl.h index 672e5d91c23..6005f48e5e4 100644 --- a/GraphicsView/include/CGAL/Qt/camera_impl.h +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -160,10 +160,11 @@ frustrum coherence. If your Camera is used without a CGAL::QGLViewer (offscreen rendering, shadow maps), use setAspectRatio() instead to define the projection matrix. */ CGAL_INLINE_FUNCTION -void Camera::setScreenWidthAndHeight(int width, int height) { +void Camera::setScreenWidthAndHeight(int width, int height, qreal devicePixelRatio) { // Prevent negative and zero dimensions that would cause divisions by zero. screenWidth_ = width > 0 ? width : 1; screenHeight_ = height > 0 ? height : 1; + devicePixelRatio_ = devicePixelRatio; projectionMatrixIsUpToDate_ = false; } @@ -884,8 +885,7 @@ Vec Camera::pointUnderPixel(const QPoint &pixel, bool &found) const { // Qt uses upper corner for its origin while GL uses the lower corner. if(auto p = dynamic_cast(parent())) { - p->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1, - GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(pixel, p, this); } found = depth < 1.0; Vec point(pixel.x(), pixel.y(), depth); diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 70fdfdd9a15..07eb161909e 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -807,7 +807,7 @@ void CGAL::QGLViewer::setCamera(qglviewer::Camera *const camera) { camera->setSceneRadius(sceneRadius()); camera->setSceneCenter(sceneCenter()); - camera->setScreenWidthAndHeight(width(), height()); + camera->setScreenWidthAndHeight(width(), height(), devicePixelRatio()); // Disconnect current camera from this viewer. disconnect(this->camera()->frame(), SIGNAL(manipulated()), this, @@ -1147,7 +1147,9 @@ void CGAL::QGLViewer::beginSelection(const QPoint &point) { makeCurrent(); glEnable(GL_SCISSOR_TEST); - glScissor(point.x(), camera()->screenHeight()-1-point.y(), 1, 1); + glScissor(point.x() * devicePixelRatio(), + (camera()->screenHeight() - point.y()) * devicePixelRatio() - 1, 1, + 1); } /*! This method is called by select() after scene elements were drawn by @@ -2369,7 +2371,7 @@ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::resizeGL(int width, int height) { QOpenGLWidget::resizeGL(width, height); glViewport(0, 0, GLint(width), GLint(height)); - camera()->setScreenWidthAndHeight(this->width(), this->height()); + camera()->setScreenWidthAndHeight(this->width(), this->height(), this->devicePixelRatio()); } ////////////////////////////////////////////////////////////////////////// @@ -3187,10 +3189,11 @@ void CGAL::QGLViewer::drawVisualHints() { mvpMatrix.ortho(-1,1,-1,1,-1,1); size=30*devicePixelRatio(); rendering_program.setUniformValue("mvp_matrix", mvpMatrix); - glViewport(GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), - GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); - glScissor (GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), - GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); + const auto point_2d = camera()->projectedCoordinatesOf(camera()->pivotPoint()); + glViewport(GLint(point_2d.x*devicePixelRatio()-size/2), + GLint((height() - point_2d.y)*devicePixelRatio()-size/2), size, size); + glScissor (GLint(point_2d.x*devicePixelRatio()-size/2), + GLint((height() - point_2d.y)*devicePixelRatio()-size/2), size, size); rendering_program.setUniformValue("color", QColor(::Qt::black)); glDisable(GL_DEPTH_TEST); glDrawArrays(GL_LINES, 0, static_cast(4)); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index 428a0b2611e..72ef02c7c4c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -116,11 +116,7 @@ private: boost::optional fc; Viewer_interface* viewer; void getPixel(const QPoint& e) { - float data[3]; - int vp[4]; - viewer->glGetIntegerv(GL_VIEWPORT, vp); - viewer->glReadPixels(e.x(), vp[3] - e.y(), 1, 1, GL_RGB, GL_FLOAT, data); - + const auto data = read_pixel_as_float_rgb(e, viewer, viewer->camera()); if(fc) { Q_EMIT x(QString::number((*fc)(data[0]), 'f', 6 )); } else if(ic) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index f4ceff2c056..0013271d9d6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -1049,11 +1049,7 @@ void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *vie viewer->setBackgroundColor(::Qt::white); draw_picking(viewer); - int rowLength = deviceWidth * 4; // data asked in RGBA,so 4 bytes. - const static int dataLength = rowLength * deviceHeight; - GLubyte* buffer = new GLubyte[dataLength]; - // Qt uses upper corner for its origin while GL uses the lower corner. - viewer->glReadPixels(picked_pixel.x(), deviceHeight-1-picked_pixel.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + const auto buffer = read_pixel_as_ubyte_rgba(picked_pixel, viewer, viewer->camera()); //decode ID and pick (don't forget the case nothing is picked if(!(buffer[0]==buffer[1] && buffer[1]==buffer[2])) { @@ -1080,7 +1076,6 @@ void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *vie } } } - delete[] buffer; viewer->setBackgroundColor(bgColor); fbo->release(); delete fbo; diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 1e17db5fffc..220168f2351 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -564,9 +564,8 @@ void Scene::renderScene(const QList &items, if(with_names) { // read depth buffer at pick location; - float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - if (depth != 1.0) + float depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); + if (depth < 2.0) { //add object to list of picked objects; picked_item_IDs[depth] = index; @@ -635,7 +634,7 @@ void Scene::renderWireScene(const QList &items, // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; @@ -677,7 +676,7 @@ void Scene::renderPointScene(const QList &items, if(item.renderingMode() == Points && with_names) { // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 29e0685ec51..b064cf4573f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -211,7 +211,7 @@ void Scene_group_item::renderChildren(Viewer_interface *viewer, if(with_names) { // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; diff --git a/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp b/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp index 836b4641636..fac56fbda9b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp @@ -187,8 +187,6 @@ void Scene_spheres_item::draw(Viewer_interface *viewer) const setBuffersFilled(true); setBuffersInit(viewer, true); } - int deviceWidth = viewer->camera()->screenWidth(); - int deviceHeight = viewer->camera()->screenHeight(); if(d->has_plane) { QVector4D cp = cgal_plane_to_vector4d(d->plane); @@ -207,12 +205,8 @@ void Scene_spheres_item::draw(Viewer_interface *viewer) const } if(d->pickable && (d->spheres.size() > 1 && viewer->inDrawWithNames())) { - int rowLength = deviceWidth * 4; // data asked in RGBA,so 4 bytes. - const static int dataLength = rowLength * deviceHeight; - GLubyte* buffer = new GLubyte[dataLength]; - // Qt uses upper corner for its origin while GL uses the lower corner. QPoint picking_target = viewer->mapFromGlobal(QCursor::pos()); - viewer->glReadPixels(picking_target.x(), deviceHeight-1-picking_target.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + const auto buffer = read_pixel_as_ubyte_rgba(picking_target, viewer, viewer->camera()); int ID = (buffer[0] + buffer[1] * 256 +buffer[2] * 256*256) ; if(buffer[0]*buffer[1]*buffer[2] < 255*255*255) { diff --git a/Triangulation_3/demo/Triangulation_3/Viewer.cpp b/Triangulation_3/demo/Triangulation_3/Viewer.cpp index 62937f5a5bc..8aa6f1baddb 100644 --- a/Triangulation_3/demo/Triangulation_3/Viewer.cpp +++ b/Triangulation_3/demo/Triangulation_3/Viewer.cpp @@ -1696,9 +1696,9 @@ void Viewer::drawWithNames() rendering_program.release(); //read depth and store in map - GLfloat depth = 1.0f; - glReadPixels(picking_pos.x(),camera()->screenHeight()-1-picking_pos.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - if (depth != 1.0) + GLfloat depth = 2.0f; + depth = read_depth_under_pixel(picking_pos, this, this->camera()); + if (depth < 2.0f) { picked_IDs[depth] = i; } @@ -1740,9 +1740,9 @@ void Viewer::drawWithNames() rendering_program.release(); //read depth and store in map - GLfloat depth = 1.0f; - glReadPixels(picking_pos.x(),camera()->screenHeight()-1-picking_pos.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - if (depth != 1.0) + GLfloat depth = 2.0f; + depth = read_depth_under_pixel(picking_pos, this, this->camera()); + if (depth < 2.0f) { picked_IDs[depth] = -1; }