Add depth-peeling to the scene.

This commit is contained in:
Maxime Gimeno 2018-05-02 11:05:05 +02:00
parent 7ac433c388
commit 1882658a94
16 changed files with 900 additions and 153 deletions

View File

@ -807,8 +807,9 @@ private Q_SLOTS:
this, SLOT(erase_group())); this, SLOT(erase_group()));
group_map.remove(img_item); group_map.remove(img_item);
QList<int> deletion; QList<int> deletion;
Q_FOREACH(Scene_item* child, group->getChildren()) Q_FOREACH(Scene_interface::Item_id id, group->getChildren())
{ {
Scene_item* child = group->getChild(id);
group->unlockChild(child); group->unlockChild(child);
deletion.append(scene->item_id(child)); deletion.append(scene->item_id(child));
} }

View File

@ -24,6 +24,7 @@
#include <QList> #include <QList>
#include <QAbstractProxyModel> #include <QAbstractProxyModel>
#include <QMimeData> #include <QMimeData>
#include <QOpenGLFramebufferObject>
Scene::Scene(QObject* parent) Scene::Scene(QObject* parent)
@ -37,6 +38,8 @@ Scene::Scene(QObject* parent)
double, double, double)), double, double, double)),
this, SLOT(setSelectionRay(double, double, double, this, SLOT(setSelectionRay(double, double, double,
double, double, double))); double, double, double)));
connect(this, SIGNAL(indexErased(Scene_interface::Item_id)),
this, SLOT(adjustIds(Scene_interface::Item_id)));
picked = false; picked = false;
gl_init = false; gl_init = false;
@ -46,6 +49,7 @@ Scene::addItem(CGAL::Three::Scene_item* item)
{ {
Bbox bbox_before = bbox(); Bbox bbox_before = bbox();
m_entries.push_back(item); m_entries.push_back(item);
Item_id id = m_entries.size() - 1;
connect(item, SIGNAL(itemChanged()), connect(item, SIGNAL(itemChanged()),
this, SLOT(itemChanged())); this, SLOT(itemChanged()));
connect(item, SIGNAL(itemVisibilityChanged()), connect(item, SIGNAL(itemVisibilityChanged()),
@ -70,7 +74,7 @@ Scene::addItem(CGAL::Three::Scene_item* item)
index_map[list.at(i)->index()] = m_entries.size() -1; index_map[list.at(i)->index()] = m_entries.size() -1;
} }
Q_EMIT updated(); Q_EMIT updated();
Item_id id = m_entries.size() - 1; children.push_back(id);
Q_EMIT newItem(id); Q_EMIT newItem(id);
CGAL::Three::Scene_group_item* group = CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item); qobject_cast<CGAL::Three::Scene_group_item*>(item);
@ -95,13 +99,14 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
qobject_cast<CGAL::Three::Scene_group_item*>(m_entries[index]); qobject_cast<CGAL::Three::Scene_group_item*>(m_entries[index]);
if(group) if(group)
{ {
QList<int> children; QList<int> group_children;
Q_FOREACH(CGAL::Three::Scene_item* child, group->getChildren()) Q_FOREACH(Item_id id, group->getChildren())
{ {
CGAL::Three::Scene_item* child = group->getChild(id);
group->unlockChild(child); group->unlockChild(child);
children << item_id(child); group_children << item_id(child);
} }
erase(children); erase(group_children);
} }
CGAL::Three::Scene_group_item* parent = m_entries[index]->parentGroup(); CGAL::Three::Scene_group_item* parent = m_entries[index]->parentGroup();
bool is_locked = false; bool is_locked = false;
@ -166,7 +171,10 @@ Scene::erase(Scene::Item_id index)
item->parentGroup()->removeChild(item); item->parentGroup()->removeChild(item);
//removes the item from all groups that contain it //removes the item from all groups that contain it
m_entries.removeAll(item); Item_id removed_item = item_id(item);
children.removeAll(removed_item);
indexErased(removed_item);
m_entries.removeAll(item);
Q_EMIT itemAboutToBeDestroyed(item); Q_EMIT itemAboutToBeDestroyed(item);
item->aboutToBeDestroyed(); item->aboutToBeDestroyed();
item->deleteLater(); item->deleteLater();
@ -207,8 +215,9 @@ Scene::erase(QList<int> indices)
Scene_group_item* group = qobject_cast<Scene_group_item*>(item); Scene_group_item* group = qobject_cast<Scene_group_item*>(item);
if(group) if(group)
{ {
Q_FOREACH(Scene_item* child, group->getChildren()) Q_FOREACH(Item_id id, group->getChildren())
{ {
CGAL::Three::Scene_item* child = group->getChild(id);
if(!to_be_removed.contains(child)) if(!to_be_removed.contains(child))
to_be_removed.push_back(child); to_be_removed.push_back(child);
} }
@ -220,7 +229,11 @@ Scene::erase(QList<int> indices)
Q_FOREACH(Scene_item* item, to_be_removed) { Q_FOREACH(Scene_item* item, to_be_removed) {
if(item->parentGroup()) if(item->parentGroup())
item->parentGroup()->removeChild(item); item->parentGroup()->removeChild(item);
m_entries.removeAll(item); Item_id removed_item = item_id(item);
children.removeAll(removed_item);
indexErased(removed_item);
m_entries.removeAll(item);
Q_EMIT itemAboutToBeDestroyed(item); Q_EMIT itemAboutToBeDestroyed(item);
item->aboutToBeDestroyed(); item->aboutToBeDestroyed();
item->deleteLater(); item->deleteLater();
@ -255,6 +268,7 @@ void Scene::remove_item_from_groups(Scene_item* item)
if(group) if(group)
{ {
group->removeChild(item); group->removeChild(item);
children.push_back(item_id(item));
} }
} }
Scene::~Scene() Scene::~Scene()
@ -309,21 +323,95 @@ Scene::duplicate(Item_id index)
void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer)
{ {
//Setting the light options //Vertex source code
const char vertex_source[] =
{
"#version 120 \n"
"attribute highp vec4 vertex; \n"
"attribute highp vec2 v_texCoord; \n"
"uniform highp mat4 projection_matrix; \n"
"varying highp vec2 f_texCoord; \n"
"void main(void) \n"
"{ \n"
" f_texCoord = v_texCoord; \n"
" gl_Position = projection_matrix * vertex; \n"
"} \n"
// Create light components };
GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; //Fragment source code
GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0, 1.0f }; const char fragment_source[] =
GLfloat specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; {
GLfloat position[] = { 0.0f, 0.0f, 1.0f, 1.0f }; "#version 120 \n"
"varying highp vec2 f_texCoord; \n"
"uniform sampler2D texture; \n"
"void main(void) \n"
"{ \n"
" gl_FragColor = texture2D(texture, f_texCoord); \n"
"} \n"
};
// Assign created components to GL_LIGHT0
viewer->glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
viewer->glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
viewer->glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
viewer->glLightfv(GL_LIGHT0, GL_POSITION, position);
gl_init = true; QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex);
if(!vertex_shader->compileSourceCode(vertex_source))
{
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
}
QOpenGLShader *fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
if(!fragment_shader->compileSourceCode(fragment_source))
{
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
}
if(!program.addShader(vertex_shader))
{
std::cerr<<"adding vertex shader FAILED"<<std::endl;
}
if(!program.addShader(fragment_shader))
{
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
if(!program.link())
{
//std::cerr<<"linking Program FAILED"<<std::endl;
qDebug() << program.log();
}
points[0] = -1.0f; points[1] = -1.0f; points[2] = 0.0f;
points[3] = 1.0f; points[4] = 1.0f; points[5] = 0.0f;
points[6] = 1.0f; points[7] = -1.0f; points[8] = 0.0f;
points[9] = -1.0f; points[10] = -1.0f; points[11] = 0.0f;
points[12] = -1.0f; points[13] = 1.0f; points[14] = 0.0f;
points[15] = 1.0f; points[16] = 1.0f; points[17] = 0.0f;
uvs[0] = 0.0f; uvs[1] = 0.0f;
uvs[2] = 1.0f; uvs[3] = 1.0f;
uvs[4] = 1.0f; uvs[5] = 0.0f;
uvs[6] = 0.0f; uvs[7] = 0.0f;
uvs[8] = 0.0f; uvs[9] = 1.0f;
uvs[10] = 1.0f; uvs[11] = 1.0f;
vbo[0].create();
vbo[1].create();
viewer->makeCurrent();
vao = new QOpenGLVertexArrayObject();
vao->create();
program.bind();
vao->bind();
vbo[0].bind();
vbo[0].allocate(points, 18 * sizeof(float));
program.enableAttributeArray("vertex");
program.setAttributeArray("vertex", GL_FLOAT, 0, 3);
vbo[0].release();
vbo[1].bind();
vbo[1].allocate(uvs, 12 * sizeof(float));
program.enableAttributeArray("v_texCoord");
program.setAttributeArray("v_texCoord", GL_FLOAT, 0, 2);
vbo[1].release();
vao->release();
program.release();
gl_init = true;
} }
void Scene::s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *rmv_itm) void Scene::s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *rmv_itm)
@ -368,14 +456,320 @@ bool item_should_be_skipped_in_draw(Scene_item* item) {
return true; return true;
} }
void Scene::renderScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names,
int pass,
bool writing_depth,
QOpenGLFramebufferObject *fbo)
{
viewer->makeCurrent();
viewer->setCurrentPass(pass);
viewer->setDepthWriting(writing_depth);
viewer->setDepthPeelingFbo(fbo);
Q_FOREACH(Scene_interface::Item_id index, items)
{
CGAL::Three::Scene_item& item = *m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(&item);
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
else
{
item.selection_changed(false);
}
if(group ||item.visible())
{
if( group || item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud)
{
if(with_names) {
viewer->glClearDepth(1.0);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if(item.renderingMode() == Gouraud)
viewer->glShadeModel(GL_SMOOTH);
else
viewer->glShadeModel(GL_FLAT);
item.draw(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);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = index;
}
}
if(group)
group->renderChildren(viewer, picked_item_IDs, picked_pixel, with_names);
}
}
}
void Scene::renderWireScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names)
{
Q_FOREACH(Scene_interface::Item_id index, items)
{
CGAL::Three::Scene_item& item = *m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(&item);
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
else
{
item.selection_changed(false);
}
if(group ||item.visible())
{
if( group || (!with_names && item.renderingMode() == FlatPlusEdges )
|| item.renderingMode() == Wireframe
|| item.renderingMode() == PointsPlusNormals)
{
viewer->glDisable(GL_LIGHTING);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
item.drawEdges(viewer);
}
else{
if( item.renderingMode() == PointsPlusNormals ){
viewer->glDisable(GL_LIGHTING);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
else
{
item.selection_changed(false);
}
item.drawEdges(viewer);
}
}
if((item.renderingMode() == Wireframe || item.renderingMode() == PointsPlusNormals )
&& 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)
{
//add object to list of picked objects;
picked_item_IDs[depth] = index;
}
}
}
}
}
void Scene::renderPointScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names)
{
Q_FOREACH(Scene_interface::Item_id index, items)
{
CGAL::Three::Scene_item& item = *m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(&item);
if(group ||item.visible())
{
if(item.renderingMode() == Points && with_names) {
viewer->glClearDepth(1.0);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if(group || item.renderingMode() == Points ||
(item.renderingMode() == PointsPlusNormals) ||
(item.renderingMode() == ShadedPoints))
{
viewer->glDisable(GL_LIGHTING);
viewer->glPointSize(3.0f);
viewer->glLineWidth(1.0f);
item.drawPoints(viewer);
}
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);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = index;
}
}
}
}
}
bool Scene::has_alpha()
{
Q_FOREACH(Scene_item* item, m_entries)
if(item->alpha() != 1.0f)
return true;
return false;
}
void void
Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
{ {
viewer->makeCurrent();
QMap<float, int> picked_item_IDs; QMap<float, int> picked_item_IDs;
if(with_names) if(with_names)
viewer->glEnable(GL_DEPTH_TEST); viewer->glEnable(GL_DEPTH_TEST);
if(!gl_init) if(!gl_init)
initializeGL(viewer); initializeGL(viewer);
renderScene(children, viewer, picked_item_IDs, with_names, -1, false, NULL);
if(!with_names && has_alpha())
{
std::vector<QOpenGLFramebufferObject*> fbos;
std::vector<QOpenGLFramebufferObject*> depth_test;
QColor background = viewer->backgroundColor();
fbos.resize((int)viewer->total_pass());
depth_test.resize((int)viewer->total_pass()-1);
//first pass
fbos[0] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
fbos[0]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, 0,false, NULL);
fbos[0]->release();
depth_test[0] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
depth_test[0]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, 0,true, NULL);
depth_test[0]->release();
//other passes
for(int i=1; i<viewer->total_pass()-1; ++i)
{
fbos[i] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
fbos[i]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderWireScene(children, viewer, picked_item_IDs, false);
renderPointScene(children, viewer, picked_item_IDs, false);
renderScene(children, viewer, picked_item_IDs, false, i, false, depth_test[i-1]);
fbos[i]->release();
depth_test[i] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
depth_test[i]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, i, true, depth_test[i-1]);
depth_test[i]->release();
}
//last pass
fbos[(int)viewer->total_pass()-1] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F);
fbos[(int)viewer->total_pass()-1]->bind();
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
viewer->glDepthFunc(GL_LESS);
viewer->glEnable(GL_ALPHA_TEST);
viewer->glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
viewer->glClearDepth(1);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene(children, viewer, picked_item_IDs, false, (int)viewer->total_pass()-1, false, depth_test[(int)viewer->total_pass()-2]);
fbos[(int)viewer->total_pass()-1]->release();
//blending
program.bind();
vao->bind();
viewer->glClearColor(background.redF(),
background.greenF(),
background.blueF(),
1.0f);
viewer->glDisable(GL_DEPTH_TEST);
viewer->glClear(GL_COLOR_BUFFER_BIT);
viewer->glEnable(GL_BLEND);
viewer->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
QMatrix4x4 proj_mat;
proj_mat.setToIdentity();
proj_mat.ortho(-1,1,-1,1,0,1);
program.setUniformValue("projection_matrix", proj_mat);
for(int i=0; i< (int)viewer->total_pass()-1; ++i)
delete depth_test[i];
for(int i = (int)viewer->total_pass()-1; i>=0; --i)
{
viewer->glBindTexture(GL_TEXTURE_2D, fbos[i]->texture());
viewer->glDrawArrays(GL_TRIANGLES,0,static_cast<GLsizei>(6));
delete fbos[i];
}
viewer->glDisable(GL_BLEND);
viewer->glEnable(GL_DEPTH_TEST);
vao->release();
program.release();
}
viewer->glDepthFunc(GL_LEQUAL);
// Wireframe OpenGL drawing
renderWireScene(children, viewer, picked_item_IDs, with_names);
// Points OpenGL drawing
renderPointScene(children, viewer, picked_item_IDs, with_names);
/*{
// Flat/Gouraud OpenGL drawing // Flat/Gouraud OpenGL drawing
for(int index = 0; index < m_entries.size(); ++index) for(int index = 0; index < m_entries.size(); ++index)
{ {
@ -575,7 +969,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
} }
} }
} }
//}*/
if(with_names) if(with_names)
{ {
QList<float> depths = picked_item_IDs.keys(); QList<float> depths = picked_item_IDs.keys();
@ -784,8 +1178,11 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
CGAL::Three::Scene_group_item* group = CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i)); qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group) if(group)
Q_FOREACH(Scene_item* child, group->getChildren()) Q_FOREACH(Item_id id, group->getChildren())
{
CGAL::Three::Scene_item* child = item(id);
groups_children << item_id(child); groups_children << item_id(child);
}
} }
// Insure that children of selected groups will not be added twice // Insure that children of selected groups will not be added twice
Q_FOREACH(int i, selected_items_list) Q_FOREACH(int i, selected_items_list)
@ -803,7 +1200,7 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
if(group) if(group)
{ {
Q_FOREACH(int id, selected_items_list) Q_FOREACH(int id, selected_items_list)
if(group->getChildren().contains(item(id))) if(group->getChildren().contains(id))
{ {
one_contained = true; one_contained = true;
break; break;
@ -821,6 +1218,7 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
if(item->parentGroup()) if(item->parentGroup())
{ {
item->parentGroup()->removeChild(item); item->parentGroup()->removeChild(item);
children.push_back(item_id(item));
} }
} }
redraw_model(); redraw_model();
@ -844,7 +1242,7 @@ void Scene::moveRowUp()
Scene_group_item* group = selected_item->parentGroup(); Scene_group_item* group = selected_item->parentGroup();
if(group) if(group)
{ {
int id = group->getChildren().indexOf(selected_item); int id = group->getChildren().indexOf(item_id(selected_item));
group->moveUp(id); group->moveUp(id);
} }
} }
@ -852,8 +1250,9 @@ void Scene::moveRowUp()
{ {
//if not in group //if not in group
QModelIndex baseId = index_map.key(mainSelectionIndex()); QModelIndex baseId = index_map.key(mainSelectionIndex());
int newId = index_map.value(index(baseId.row()-1, baseId.column(),baseId.parent())) ; int newId = children.indexOf(
m_entries.move(mainSelectionIndex(), newId); index_map.value(index(baseId.row()-1, baseId.column(),baseId.parent()))) ;
children.move(children.indexOf(item_id(selected_item)), newId);
} }
redraw_model(); redraw_model();
setSelectedItem(m_entries.indexOf(selected_item)); setSelectedItem(m_entries.indexOf(selected_item));
@ -869,7 +1268,7 @@ void Scene::moveRowDown()
Scene_group_item* group = selected_item->parentGroup(); Scene_group_item* group = selected_item->parentGroup();
if(group) if(group)
{ {
int id = group->getChildren().indexOf(selected_item); int id = group->getChildren().indexOf(item_id(selected_item));
group->moveDown(id); group->moveDown(id);
} }
} }
@ -877,7 +1276,8 @@ void Scene::moveRowDown()
{ {
//if not in group //if not in group
QModelIndex baseId = index_map.key(mainSelectionIndex()); QModelIndex baseId = index_map.key(mainSelectionIndex());
int newId = index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent())) ; int newId = children.indexOf(
index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent()))) ;
m_entries.move(mainSelectionIndex(), newId); m_entries.move(mainSelectionIndex(), newId);
} }
redraw_model(); redraw_model();
@ -1158,9 +1558,10 @@ void Scene::redraw_model()
clear(); clear();
index_map.clear(); index_map.clear();
//fills the model //fills the model
Q_FOREACH(Scene_item* item, m_entries) Q_FOREACH(Item_id id, children)
{ {
organize_items(item, invisibleRootItem(), 0); organize_items(m_entries[id], invisibleRootItem(), 0);
} }
Q_EMIT restoreCollapsedState(); Q_EMIT restoreCollapsedState();
} }
@ -1172,7 +1573,12 @@ void Scene::changeGroup(Scene_item *item, CGAL::Three::Scene_group_item *target_
if(item->parentGroup()->isChildLocked(item)) if(item->parentGroup()->isChildLocked(item))
return; return;
item->parentGroup()->removeChild(item); item->parentGroup()->removeChild(item);
children.push_back(item_id(item));
} }
else
{
children.removeAll(item_id(item));
}
//add the item to the target group //add the item to the target group
target_group->addChild(item); target_group->addChild(item);
item->moveToGroup(target_group); item->moveToGroup(target_group);
@ -1292,8 +1698,9 @@ void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop)
qobject_cast<CGAL::Three::Scene_group_item*>(item); qobject_cast<CGAL::Three::Scene_group_item*>(item);
if(group) if(group)
{ {
Q_FOREACH(Scene_item*child, group->getChildren()) Q_FOREACH(Item_id id, group->getChildren())
{ {
CGAL::Three::Scene_item* child = group->getChild(id);
organize_items(child, list.first(), loop+1); organize_items(child, list.first(), loop+1);
} }
} }
@ -1332,6 +1739,8 @@ QList<QModelIndex> Scene::getModelIndexFromId(int id) const
void Scene::addGroup(Scene_group_item* group) void Scene::addGroup(Scene_group_item* group)
{ {
connect(this, SIGNAL(drawFinished()), group, SLOT(resetDraw())); connect(this, SIGNAL(drawFinished()), group, SLOT(resetDraw()));
connect(this, SIGNAL(indexErased(Scene_interface::Item_id)),
group, SLOT(adjustIds(Scene_interface::Item_id)));
group->setScene(this); group->setScene(this);
} }
@ -1387,3 +1796,16 @@ void Scene::zoomToPosition(QPoint point, Viewer_interface *viewer)
} }
} }
} }
void Scene::adjustIds(Item_id removed_id)
{
for(int i = 0; i < children.size(); ++i)
{
if(children[i] >= removed_id)
--children[i];
}
for(int i = removed_id; i < numberOfEntries(); ++i)
{
m_entries[i]->setId(i-1);//the signal is emitted before m_entries is amputed from the item, so new id is current id -1.
}
}

View File

@ -24,6 +24,7 @@
#include <CGAL/Three/Scene_group_item.h> #include <CGAL/Three/Scene_group_item.h>
class QEvent; class QEvent;
class QMouseEvent; class QMouseEvent;
class QOpenGLFramebufferObject;
namespace CGAL { namespace Three{ class Viewer_interface;}} namespace CGAL { namespace Three{ class Viewer_interface;}}
//! This class is not supposed to be used by Plugins, but sometimes you may need access to //! This class is not supposed to be used by Plugins, but sometimes you may need access to
@ -190,8 +191,8 @@ public Q_SLOTS:
if(group) if(group)
{ {
QList<int> list; QList<int> list;
Q_FOREACH(CGAL::Three::Scene_item* child, group->getChildrenForSelection()) Q_FOREACH(Item_id id, group->getChildrenForSelection())
list<<m_entries.indexOf(child); list<<id;
l << setSelectedItemsList(list); l << setSelectedItemsList(list);
} }
@ -210,6 +211,8 @@ public Q_SLOTS:
Q_SIGNALS: Q_SIGNALS:
//generated automatically by moc //generated automatically by moc
//!Is emitted when the ids of the items are changed.
void indexErased(Scene_interface::Item_id id);
//! Emit this to mark `modelindex` as selected in the Geometric Objects view. //! Emit this to mark `modelindex` as selected in the Geometric Objects view.
void itemPicked(const QModelIndex& modelindex); void itemPicked(const QModelIndex& modelindex);
//! Is emitted when a new item is added to the scene. //! Is emitted when a new item is added to the scene.
@ -233,6 +236,7 @@ Q_SIGNALS:
void drawFinished(); void drawFinished();
private Q_SLOTS: private Q_SLOTS:
// Casts a selection ray and calls the item function select. // Casts a selection ray and calls the item function select.
void adjustIds(Scene_interface::Item_id removed_id);
void setSelectionRay(double, double, double, double, double, double); void setSelectionRay(double, double, double, double, double, double);
void callDraw(){ CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->update();} void callDraw(){ CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->update();}
void s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *); void s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *);
@ -241,12 +245,24 @@ private:
* to its current renderingMode. If with_names is true, uses * to its current renderingMode. If with_names is true, uses
* the OpenGL mode GL_WITH_NAMES, essentially used for the picking.*/ * the OpenGL mode GL_WITH_NAMES, essentially used for the picking.*/
void draw_aux(bool with_names, CGAL::Three::Viewer_interface*); void draw_aux(bool with_names, CGAL::Three::Viewer_interface*);
bool has_alpha();
void renderScene(const QList<Scene_interface::Item_id > &items,
CGAL::Three::Viewer_interface* viewer, QMap<float, int> &picked_item_IDs, bool with_names,
int pass, bool writing_depth,
QOpenGLFramebufferObject* fbo);
void renderWireScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer, QMap<float, int> &picked_item_IDs, bool with_names);
void renderPointScene(const QList<Scene_interface::Item_id> &items,
Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
bool with_names);
// Re-draw the hierarchy of the view. // Re-draw the hierarchy of the view.
void organize_items(CGAL::Three::Scene_item* item, QStandardItem *root, int loop); void organize_items(CGAL::Three::Scene_item* item, QStandardItem *root, int loop);
// List of Scene_items. // List of Scene_items.
typedef QList<CGAL::Three::Scene_item*> Entries; typedef QList<CGAL::Three::Scene_item*> Entries;
//List containing all the scene_items. //List containing all the scene_items.
Entries m_entries; Entries m_entries;
QList<Item_id> children;
// Index of the currently selected item. // Index of the currently selected item.
int selected_item; int selected_item;
//List of indices of the currently selected items. //List of indices of the currently selected items.
@ -259,6 +275,11 @@ private:
QPoint picked_pixel; QPoint picked_pixel;
bool gl_init; bool gl_init;
QMap<QModelIndex, int> index_map; QMap<QModelIndex, int> index_map;
float points[18];
float uvs[12];
QOpenGLShaderProgram program;
QOpenGLVertexArrayObject* vao;
mutable QOpenGLBuffer vbo[2];
}; // end class Scene }; // end class Scene

View File

@ -119,7 +119,7 @@ public:
void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE;
void drawPoints(CGAL::Three::Viewer_interface * viewer) const Q_DECL_OVERRIDE; void drawPoints(CGAL::Three::Viewer_interface * viewer) const Q_DECL_OVERRIDE;
//When selecting a c3t3 item, we don't want to select its children, so we can still apply Operations to it //When selecting a c3t3 item, we don't want to select its children, so we can still apply Operations to it
QList<Scene_item*> getChildrenForSelection() const Q_DECL_OVERRIDE { return QList<Scene_item*>(); } QList<Scene_interface::Item_id> getChildrenForSelection() const Q_DECL_OVERRIDE { return QList<Scene_interface::Item_id>(); }
public: public:
QMenu* contextMenu() Q_DECL_OVERRIDE; QMenu* contextMenu() Q_DECL_OVERRIDE;
void copyProperties(Scene_item *) Q_DECL_OVERRIDE; void copyProperties(Scene_item *) Q_DECL_OVERRIDE;

View File

@ -14,16 +14,16 @@ Scene_group_item::Scene_group_item(QString name, int nb_vbos, int nb_vaos )
bool Scene_group_item::isFinite() const bool Scene_group_item::isFinite() const
{ {
Q_FOREACH(Scene_item *item, children) Q_FOREACH(Scene_interface::Item_id id, children)
if(!item->isFinite()){ if(!getChild(id)->isFinite()){
return false; return false;
} }
return true; return true;
} }
bool Scene_group_item::isEmpty() const { bool Scene_group_item::isEmpty() const {
Q_FOREACH(Scene_item *item, children) Q_FOREACH(Scene_interface::Item_id id, children)
if(!item->isEmpty()){ if(!getChild(id)->isEmpty()){
return true; return true;
} }
return true; return true;
@ -37,8 +37,8 @@ Scene_group_item::Bbox Scene_group_item::bbox() const
bool Scene_group_item::supportsRenderingMode(RenderingMode m) const { bool Scene_group_item::supportsRenderingMode(RenderingMode m) const {
Q_FOREACH(Scene_item* item, children) Q_FOREACH(Scene_interface::Item_id id, children)
if(!item->supportsRenderingMode(m)) if(!getChild(id)->supportsRenderingMode(m))
return false; return false;
return true; return true;
@ -53,38 +53,50 @@ QString Scene_group_item::toolTip() const {
void Scene_group_item::addChild(Scene_item* new_item) void Scene_group_item::addChild(Scene_item* new_item)
{ {
if(!children.contains(new_item)) if(!children.contains(scene->item_id(new_item)))
{ {
children.append(new_item); children.append(scene->item_id(new_item));
update_group_number(new_item, has_group+1); update_group_number(new_item, has_group+1);
} }
} }
void Scene_group_item::addChild(Scene_interface::Item_id new_id)
{
if(!children.contains(new_id))
{
children.append(new_id);
update_group_number(getChild(new_id), has_group+1);
}
}
void Scene_group_item::update_group_number(Scene_item * new_item, int n) void Scene_group_item::update_group_number(Scene_item * new_item, int n)
{ {
Scene_group_item* group = Scene_group_item* group =
qobject_cast<Scene_group_item*>(new_item); qobject_cast<Scene_group_item*>(new_item);
if(group) if(group)
Q_FOREACH(Scene_item* child, group->getChildren()) Q_FOREACH(Scene_interface::Item_id id, group->getChildren()){
update_group_number(child,n+1);
update_group_number(getChild(id),n+1);
}
new_item->has_group = n; new_item->has_group = n;
} }
void Scene_group_item::setColor(QColor c) void Scene_group_item::setColor(QColor c)
{ {
Scene_item::setColor(c); Scene_item::setColor(c);
Q_FOREACH(Scene_item* child, children) Q_FOREACH(Scene_interface::Item_id id, children)
{ {
child->setColor(c); getChild(id)->setColor(c);
} }
} }
void Scene_group_item::setRenderingMode(RenderingMode m) void Scene_group_item::setRenderingMode(RenderingMode m)
{ {
Scene_item::setRenderingMode(m); Scene_item::setRenderingMode(m);
Q_FOREACH(Scene_item* child, children) Q_FOREACH(Scene_interface::Item_id id, children)
{ {
Scene_item* child = getChild(id);
if(child->supportsRenderingMode(m)) if(child->supportsRenderingMode(m))
child->setRenderingMode(m); child->setRenderingMode(m);
} }
@ -93,8 +105,9 @@ void Scene_group_item::setRenderingMode(RenderingMode m)
void Scene_group_item::setVisible(bool b) void Scene_group_item::setVisible(bool b)
{ {
Scene_item::setVisible(b); Scene_item::setVisible(b);
Q_FOREACH(Scene_item* child, children) Q_FOREACH(Scene_interface::Item_id id, children)
{ {
Scene_item* child = getChild(id);
child->setVisible(b); child->setVisible(b);
child->itemChanged(); child->itemChanged();
} }
@ -123,7 +136,9 @@ void Scene_group_item::moveUp(int i)
void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const { void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
if(viewer->inDrawWithNames() || already_drawn ) return; if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) { Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(!child->visible()) continue; if(!child->visible()) continue;
switch(child->renderingMode()) { switch(child->renderingMode()) {
case Flat: case Flat:
@ -153,7 +168,9 @@ void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
void Scene_group_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const void Scene_group_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
{ {
if(viewer->inDrawWithNames() || already_drawn ) return; if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) { Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(!child->visible()) continue; if(!child->visible()) continue;
switch(child->renderingMode()) { switch(child->renderingMode()) {
case FlatPlusEdges: case FlatPlusEdges:
@ -183,7 +200,9 @@ void Scene_group_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
void Scene_group_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const void Scene_group_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const
{ {
if(viewer->inDrawWithNames() || already_drawn ) return; if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) { Q_FOREACH(Scene_interface::Item_id id, children)
{
Scene_item* child = getChild(id);
if(!child->visible()) continue; if(!child->visible()) continue;
switch(child->renderingMode()) { switch(child->renderingMode()) {
case Points: case Points:
@ -210,22 +229,101 @@ void Scene_group_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const
already_drawn = true; already_drawn = true;
} }
void Scene_group_item::renderChildren(Viewer_interface *viewer,
QMap<float, int>& picked_item_IDs,
const QPoint& picked_pixel,
bool with_names)
{
Q_FOREACH(Scene_interface::Item_id id, children){
if(with_names) {
viewer->glClearDepth(1.0);
viewer->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
if(id == scene->mainSelectionIndex()|| scene->selectionIndices().contains(id))
{
getChild(id)->selection_changed(true);
}
else
{
getChild(id)->selection_changed(false);
}
if(getChild(id)->visible() &&
(getChild(id)->renderingMode() == Flat ||
getChild(id)->renderingMode() == FlatPlusEdges ||
getChild(id)->renderingMode() == Gouraud))
{
getChild(id)->draw(viewer);
}
if(getChild(id)->visible() &&
(getChild(id)->renderingMode() == FlatPlusEdges
|| getChild(id)->renderingMode() == Wireframe
|| getChild(id)->renderingMode() == PointsPlusNormals))
{
getChild(id)->drawEdges(viewer);
}
if(getChild(id)->visible() &&
(getChild(id)->renderingMode() == Points ||
(getChild(id)->renderingMode() == PointsPlusNormals) ||
(getChild(id)->renderingMode() == ShadedPoints)))
{
getChild(id)->drawPoints(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);
if (depth != 1.0)
{
//add object to list of picked objects;
picked_item_IDs[depth] = id;
}
}
}
}
void Scene_group_item::lockChild(Scene_item *child) void Scene_group_item::lockChild(Scene_item *child)
{ {
if(!children.contains(child)) lockChild(scene->item_id(child));
}
void Scene_group_item::lockChild(Scene_interface::Item_id id)
{
if(!children.contains(id))
return; return;
child->setProperty("lock", true); getChild(id)->setProperty("lock", true);
}
void Scene_group_item::unlockChild(Scene_interface::Item_id id)
{
if(!children.contains(id))
return;
getChild(id)->setProperty("lock", false);
} }
void Scene_group_item::unlockChild(Scene_item *child) void Scene_group_item::unlockChild(Scene_item *child)
{ {
if(!children.contains(child)) unlockChild(scene->item_id(child));
return;
child->setProperty("lock", false);
} }
bool Scene_group_item::isChildLocked(Scene_interface::Item_id id)
{
if(!children.contains(id)
|| (!getChild(id)->property("lock").toBool()) )
return false;
return true;
}
bool Scene_group_item::isChildLocked(Scene_item *child) bool Scene_group_item::isChildLocked(Scene_item *child)
{ {
if(!children.contains(child) return isChildLocked(scene->item_id(child));
|| (!child->property("lock").toBool()) )
return false;
return true;
} }
void Scene_group_item::setAlpha(int )
{
Q_FOREACH(Scene_interface::Item_id id, children)
{
scene->item(id)->setAlpha(static_cast<int>(alpha()*255));
}
}

View File

@ -229,3 +229,15 @@ void CGAL::Three::Scene_item::compute_diag_bbox()const
); );
} }
void Scene_item::setId(int id) {cur_id = id; }
int Scene_item::getId() const { return cur_id; }
float Scene_item::alpha() const
{
return 1.0f;
}
void Scene_item::setAlpha(int )
{
}

View File

@ -64,7 +64,7 @@ public:
void smooth(std::vector<Point_3>& polyline); void smooth(std::vector<Point_3>& polyline);
//When selecting a polylineitem, we don't want to select its children, so we can still apply Operations to it //When selecting a polylineitem, we don't want to select its children, so we can still apply Operations to it
QList<Scene_item*> getChildrenForSelection() const { return QList<Scene_item*>(); } QList<Scene_interface::Item_id> getChildrenForSelection() const { return QList<Scene_interface::Item_id>(); }
public Q_SLOTS: public Q_SLOTS:
virtual void invalidateOpenGLBuffers(); virtual void invalidateOpenGLBuffers();

View File

@ -11,6 +11,9 @@
#include <QVariant> #include <QVariant>
#include <QMessageBox> #include <QMessageBox>
#include <QMenu> #include <QMenu>
#include <QWidgetAction>
#include <QSlider>
#include <QOpenGLFramebufferObject>
//#include <CGAL/boost/graph/properties_Surface_mesh.h> //#include <CGAL/boost/graph/properties_Surface_mesh.h>
#include <CGAL/Surface_mesh.h> #include <CGAL/Surface_mesh.h>
@ -91,6 +94,7 @@ struct Scene_surface_mesh_item_priv{
vertices_displayed = false; vertices_displayed = false;
edges_displayed = false; edges_displayed = false;
faces_displayed = false; faces_displayed = false;
alphaSlider = NULL;
} }
Scene_surface_mesh_item_priv(SMesh* sm, Scene_surface_mesh_item *parent): Scene_surface_mesh_item_priv(SMesh* sm, Scene_surface_mesh_item *parent):
@ -102,10 +106,13 @@ struct Scene_surface_mesh_item_priv{
vertices_displayed = false; vertices_displayed = false;
edges_displayed = false; edges_displayed = false;
faces_displayed = false; faces_displayed = false;
alphaSlider = NULL;
} }
~Scene_surface_mesh_item_priv() ~Scene_surface_mesh_item_priv()
{ {
if(alphaSlider)
delete alphaSlider;
if(smesh_) if(smesh_)
{ {
delete smesh_; delete smesh_;
@ -199,6 +206,7 @@ struct Scene_surface_mesh_item_priv{
unsigned int number_of_degenerated_faces; unsigned int number_of_degenerated_faces;
int genus; int genus;
bool self_intersect; bool self_intersect;
QSlider* alphaSlider;
}; };
const char* aabb_property_name = "Scene_surface_mesh_item aabb tree"; const char* aabb_property_name = "Scene_surface_mesh_item aabb tree";
@ -313,7 +321,13 @@ void Scene_surface_mesh_item_priv::addFlatData(Point p, EPICK::Vector_3 n, CGAL:
void Scene_surface_mesh_item_priv::compute_elements() void Scene_surface_mesh_item_priv::compute_elements()
{ {
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
if(!alphaSlider)
{
alphaSlider = new QSlider(::Qt::Horizontal);
alphaSlider->setMinimum(0);
alphaSlider->setMaximum(255);
alphaSlider->setValue(255);
}
smooth_vertices.clear(); smooth_vertices.clear();
smooth_normals.clear(); smooth_normals.clear();
flat_vertices.clear(); flat_vertices.clear();
@ -652,6 +666,7 @@ void Scene_surface_mesh_item_priv::initializeBuffers(CGAL::Three::Viewer_interfa
void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
{ {
viewer->glShadeModel(GL_SMOOTH); viewer->glShadeModel(GL_SMOOTH);
QOpenGLFramebufferObject* fbo = viewer->depthPeelingFbo();
if(!are_buffers_filled) if(!are_buffers_filled)
{ {
d->compute_elements(); d->compute_elements();
@ -664,10 +679,16 @@ void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
if(renderingMode() == Gouraud) if(renderingMode() == Gouraud)
{ {
vaos[Scene_surface_mesh_item_priv::Smooth_facets]->bind(); vaos[Scene_surface_mesh_item_priv::Smooth_facets]->bind();
if(is_selected) d->program->setAttributeValue("is_selected", is_selected);
d->program->setAttributeValue("is_selected", true); d->program->setUniformValue("comparing", viewer->currentPass() > 0);;
else d->program->setUniformValue("width", viewer->width()*1.0f);
d->program->setAttributeValue("is_selected", false); d->program->setUniformValue("height", viewer->height()*1.0f);
d->program->setUniformValue("near", (float)viewer->camera()->zNear());
d->program->setUniformValue("far", (float)viewer->camera()->zFar());
d->program->setUniformValue("writing", viewer->isDepthWriting());
d->program->setUniformValue("alpha", alpha());
if( fbo)
viewer->glBindTexture(GL_TEXTURE_2D, fbo->texture());
if(!d->has_vcolors) if(!d->has_vcolors)
d->program->setAttributeValue("colors", this->color()); d->program->setAttributeValue("colors", this->color());
viewer->glDrawElements(GL_TRIANGLES, static_cast<GLuint>(d->idx_data_.size()), viewer->glDrawElements(GL_TRIANGLES, static_cast<GLuint>(d->idx_data_.size()),
@ -683,6 +704,15 @@ void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
d->program->setAttributeValue("is_selected", false); d->program->setAttributeValue("is_selected", false);
if(!d->has_fcolors) if(!d->has_fcolors)
d->program->setAttributeValue("colors", this->color()); d->program->setAttributeValue("colors", this->color());
d->program->setUniformValue("comparing", viewer->currentPass() > 0);
d->program->setUniformValue("width", viewer->width()*1.0f);
d->program->setUniformValue("height", viewer->height()*1.0f);
d->program->setUniformValue("near", (float)viewer->camera()->zNear());
d->program->setUniformValue("far", (float)viewer->camera()->zFar());
d->program->setUniformValue("writing", viewer->isDepthWriting());
d->program->setUniformValue("alpha", alpha());
if( fbo)
viewer->glBindTexture(GL_TEXTURE_2D, fbo->texture());
viewer->glDrawArrays(GL_TRIANGLES,0,static_cast<GLsizei>(d->nb_flat/3)); viewer->glDrawArrays(GL_TRIANGLES,0,static_cast<GLsizei>(d->nb_flat/3));
vaos[Scene_surface_mesh_item_priv::Flat_facets]->release(); vaos[Scene_surface_mesh_item_priv::Flat_facets]->release();
} }
@ -1719,6 +1749,15 @@ QMenu* Scene_surface_mesh_item::contextMenu()
actionZoomToId->setObjectName("actionZoomToId"); actionZoomToId->setObjectName("actionZoomToId");
connect(actionZoomToId, &QAction::triggered, connect(actionZoomToId, &QAction::triggered,
this, &Scene_surface_mesh_item::zoomToId); this, &Scene_surface_mesh_item::zoomToId);
QMenu *container = new QMenu(tr("Alpha value"));
QWidgetAction *sliderAction = new QWidgetAction(0);
sliderAction->setDefaultWidget(d->alphaSlider);
connect(d->alphaSlider, &QSlider::valueChanged,
[this](){redraw();});
container->addAction(sliderAction);
menu->addMenu(container);
setProperty("menu_changed", true);
menu->setProperty(prop_name, true); menu->setProperty(prop_name, true);
} }
@ -1970,4 +2009,19 @@ bool Scene_surface_mesh_item::shouldDisplayIds(CGAL::Three::Scene_item *current_
return this == current_item; return this == current_item;
} }
float Scene_surface_mesh_item::alpha() const
{
if(!d->alphaSlider)
return 1.0f;
return (float)d->alphaSlider->value() / 255.0f;
}
void Scene_surface_mesh_item::setAlpha(int alpha)
{
if(!d->alphaSlider)
d->compute_elements();
d->alphaSlider->setValue(alpha);
redraw();
}
QSlider* Scene_surface_mesh_item::alphaSlider() { return d->alphaSlider; }

View File

@ -20,8 +20,8 @@
#include "properties.h" #include "properties.h"
class QSlider;
struct Scene_surface_mesh_item_priv; struct Scene_surface_mesh_item_priv;
class SCENE_SURFACE_MESH_ITEM_EXPORT Scene_surface_mesh_item class SCENE_SURFACE_MESH_ITEM_EXPORT Scene_surface_mesh_item
: public CGAL::Three::Scene_item, : public CGAL::Three::Scene_item,
public CGAL::Three::Scene_zoomable_item_interface, public CGAL::Three::Scene_zoomable_item_interface,
@ -129,6 +129,9 @@ public:
void printAllIds(CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE; void printAllIds(CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE;
bool shouldDisplayIds(CGAL::Three::Scene_item *current_item) const Q_DECL_OVERRIDE; bool shouldDisplayIds(CGAL::Three::Scene_item *current_item) const Q_DECL_OVERRIDE;
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*)const Q_DECL_OVERRIDE; bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*)const Q_DECL_OVERRIDE;
float alpha() const Q_DECL_OVERRIDE;
void setAlpha(int alpha) Q_DECL_OVERRIDE;
QSlider* alphaSlider();
Q_SIGNALS: Q_SIGNALS:
void item_is_about_to_be_changed(); void item_is_about_to_be_changed();

View File

@ -38,6 +38,18 @@ public:
QTimer messageTimer; QTimer messageTimer;
QOpenGLFunctions_4_3_Compatibility* _recentFunctions; QOpenGLFunctions_4_3_Compatibility* _recentFunctions;
bool is_2d_selection_mode; bool is_2d_selection_mode;
// D e p t h P e e l i n g
// \param pass the current pass in the Depth Peeling (transparency) algorithm.
// -1 means that no depth peeling is applied.
// \param writing_depth means that the color of the faces will be drawn in a grayscale
// according to the depth of the fragment in the shader. It is used by the transparency.
// \param fbo contains the texture used by the Depth Peeling algorithm.
// Should be NULL if pass <= 0;
int current_pass;
bool writing_depth;
int total_pass;
int current_total_pass;
QOpenGLFramebufferObject* dp_fbo;
//! The buffers used to draw the axis system //! The buffers used to draw the axis system
QOpenGLBuffer buffer; QOpenGLBuffer buffer;
@ -88,6 +100,7 @@ Viewer::Viewer(QWidget* parent, bool antialiasing)
d->shader_programs.resize(NB_OF_PROGRAMS); d->shader_programs.resize(NB_OF_PROGRAMS);
d->textRenderer = new TextRenderer(); d->textRenderer = new TextRenderer();
d->is_2d_selection_mode = false; d->is_2d_selection_mode = false;
d->total_pass = 4;
connect( d->textRenderer, SIGNAL(sendMessage(QString,int)), connect( d->textRenderer, SIGNAL(sendMessage(QString,int)),
this, SLOT(printMessage(QString,int)) ); this, SLOT(printMessage(QString,int)) );
connect(&d->messageTimer, SIGNAL(timeout()), SLOT(hideMessage())); connect(&d->messageTimer, SIGNAL(timeout()), SLOT(hideMessage()));
@ -434,6 +447,7 @@ void Viewer_impl::draw_aux(bool with_names, Viewer* viewer)
{ {
if(scene == 0) if(scene == 0)
return; return;
current_total_pass = viewer->inFastDrawing() ? total_pass/2 : total_pass;
viewer->glLineWidth(1.0f); viewer->glLineWidth(1.0f);
viewer->glPointSize(2.f); viewer->glPointSize(2.f);
viewer->glEnable(GL_POLYGON_OFFSET_FILL); viewer->glEnable(GL_POLYGON_OFFSET_FILL);
@ -1025,3 +1039,18 @@ void Viewer::setStaticImage(QImage image) { d->static_image = image; }
const QImage& Viewer:: staticImage() const { return d->static_image; } const QImage& Viewer:: staticImage() const { return d->static_image; }
void Viewer::setCurrentPass(int pass) { d->current_pass = pass; }
void Viewer::setDepthWriting(bool writing_depth) { d->writing_depth = writing_depth; }
void Viewer::setDepthPeelingFbo(QOpenGLFramebufferObject* fbo) { d->dp_fbo = fbo; }
int Viewer::currentPass()const{ return d->current_pass; }
bool Viewer::isDepthWriting()const{ return d->writing_depth; }
QOpenGLFramebufferObject *Viewer::depthPeelingFbo(){ return d->dp_fbo; }
float Viewer::total_pass()
{
return d->current_total_pass * 1.0f;
}
#include "Viewer.moc"

View File

@ -139,7 +139,13 @@ protected:
public: public:
QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() Q_DECL_OVERRIDE; QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() Q_DECL_OVERRIDE;
void setCurrentPass(int pass) Q_DECL_OVERRIDE;
void setDepthWriting(bool writing_depth) Q_DECL_OVERRIDE;
void setDepthPeelingFbo(QOpenGLFramebufferObject *fbo) Q_DECL_OVERRIDE;
int currentPass()const Q_DECL_OVERRIDE;
bool isDepthWriting()const Q_DECL_OVERRIDE;
QOpenGLFramebufferObject* depthPeelingFbo()Q_DECL_OVERRIDE;
float total_pass()Q_DECL_OVERRIDE;
}; // end class Viewer }; // end class Viewer

View File

@ -7,42 +7,64 @@ uniform highp vec4 light_pos;
uniform highp vec4 light_diff; uniform highp vec4 light_diff;
uniform highp vec4 light_spec; uniform highp vec4 light_spec;
uniform highp vec4 light_amb; uniform highp vec4 light_amb;
uniform highp float spec_power ; uniform highp float spec_power;
uniform int is_two_side; uniform int is_two_side;
uniform bool is_selected; uniform bool is_selected;
uniform bool is_clipbox_on; uniform bool is_clipbox_on;
void main(void) { uniform highp float near;
uniform highp float far;
uniform highp float width;
uniform highp float height;
uniform bool comparing;
uniform bool writing;
uniform sampler2D sampler;
if(is_clipbox_on) highp float depth(float z)
if(dist[0]>0 || {
dist[1]>0 || return (2 * near) / (far + near - z * (far - near));
dist[2]>0 ||
dist[3]>0 ||
dist[4]>0 ||
dist[5]>0)
discard;
highp vec3 L = light_pos.xyz - fP.xyz;
highp vec3 V = -fP.xyz;
highp vec3 N;
if(fN == highp vec3(0.0,0.0,0.0))
N = highp vec3(0.0,0.0,0.0);
else
N = normalize(fN);
L = normalize(L);
V = normalize(V);
highp vec3 R = reflect(-L, N);
vec4 diffuse;
if(is_two_side == 1)
diffuse = abs(dot(N,L)) * light_diff * color;
else
diffuse = max(dot(N,L), 0.0) * light_diff * color;
highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec;
vec4 ret_color = vec4((color*light_amb).xyz + diffuse.xyz + specular.xyz,1);
if(is_selected)
gl_FragColor = vec4(ret_color.r+70.0/255.0, ret_color.g+70.0/255.0, ret_color.b+70.0/255.0, 1.0);
else
gl_FragColor = ret_color;
} }
void main(void) {
if(is_clipbox_on)
if(dist[0]>0 ||
dist[1]>0 ||
dist[2]>0 ||
dist[3]>0 ||
dist[4]>0 ||
dist[5]>0)
discard;
float alpha = color.a;
float d = depth(gl_FragCoord.z);
float test = texture2D(sampler, vec2(gl_FragCoord.x/width, gl_FragCoord.y/height)).r;
if(comparing && d <= test)
discard;
if(writing)
gl_FragColor = vec4(d,d,d,1.0);
else
{
vec4 my_color = vec4(color.xyz, 1.0);
highp vec3 L = light_pos.xyz - fP.xyz;
highp vec3 V = -fP.xyz;
highp vec3 N;
if(fN == highp vec3(0.0,0.0,0.0))
N = highp vec3(0.0,0.0,0.0);
else
N = normalize(fN);
L = normalize(L);
V = normalize(V);
highp vec3 R = reflect(-L, N);
vec4 diffuse;
if(is_two_side == 1)
diffuse = abs(dot(N,L)) * light_diff * color;
else
diffuse = max(dot(N,L), 0.0) * light_diff * my_color;
highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec;
vec4 ret_color = vec4((my_color*light_amb).xyz + diffuse.xyz + specular.xyz,1);
if(is_selected)
gl_FragColor = vec4(ret_color.r+70.0/255.0, ret_color.g+70.0/255.0, ret_color.b+70.0/255.0, alpha);
else
gl_FragColor = vec4(ret_color.xyz, alpha);
}
}

View File

@ -1,7 +1,7 @@
#version 120 #version 120
attribute highp vec4 vertex; attribute highp vec4 vertex;
attribute highp vec3 normals; attribute highp vec3 normals;
attribute highp vec3 colors; attribute highp vec4 colors;
uniform highp mat4 mvp_matrix; uniform highp mat4 mvp_matrix;
uniform highp mat4 mv_matrix; uniform highp mat4 mv_matrix;
varying highp vec4 fP; varying highp vec4 fP;
@ -11,6 +11,7 @@ varying highp float dist[6];
uniform bool is_clipbox_on; uniform bool is_clipbox_on;
uniform highp mat4x4 clipbox1; uniform highp mat4x4 clipbox1;
uniform highp mat4x4 clipbox2; uniform highp mat4x4 clipbox2;
uniform highp float alpha;
void compute_distances(void) void compute_distances(void)
{ {
@ -32,8 +33,8 @@ void compute_distances(void)
void main(void) void main(void)
{ {
color = vec4(colors, 1.0); color = vec4(colors.xyz, alpha);
//
if(is_clipbox_on) if(is_clipbox_on)
compute_distances(); compute_distances();
fP = mv_matrix * vertex; fP = mv_matrix * vertex;

View File

@ -52,28 +52,48 @@ public :
//!Sets the scene; //!Sets the scene;
void setScene(Scene_interface* s) { scene = s; } void setScene(Scene_interface* s) { scene = s; }
//!Returns false to avoid disturbing the BBox of the scene. //!Returns false to avoid disturbing the BBox of the scene.
bool isFinite() const; bool isFinite() const Q_DECL_OVERRIDE;
//!Returns true to avoid disturbing the BBox of the scene. //!Returns true to avoid disturbing the BBox of the scene.
bool isEmpty() const ; bool isEmpty() const Q_DECL_OVERRIDE;
/*! /*!
* \brief Locks a child * \brief Locks a child
* *
* A locked child cannot be moved out of the group nor can it be deleted. * A locked child cannot be moved out of the group nor can it be deleted.
* Use it to prevent a child to be destroyed without its parent. * Use it to prevent a child to be destroyed without its parent.
*/ */
void lockChild(CGAL::Three::Scene_item*); void lockChild(CGAL::Three::Scene_item*);
/*! /*!
* \brief Unlocks a child * \brief Locks a child
* *
* @see lockChild() * A locked child cannot be moved out of the group nor can it be deleted.
*/ * Use it to prevent a child to be destroyed without its parent.
void unlockChild(CGAL::Three::Scene_item*); */
/*! void lockChild(Scene_interface::Item_id id);
* \brief Tells if a child is locked.
* \return true if the child is locked. /*!
* @see lockChild() * \brief Unlocks a child
*/ *
bool isChildLocked(CGAL::Three::Scene_item*); * @see lockChild()
*/
void unlockChild(CGAL::Three::Scene_item*);
/*!
* \brief Unlocks a child
*
* @see lockChild()
*/
void unlockChild(Scene_interface::Item_id id);
/*!
* \brief Tells if a child is locked.
* \return true if the child is locked.
* @see lockChild()
*/
bool isChildLocked(CGAL::Three::Scene_item*);
/*!
* \brief Tells if a child is locked.
* \return true if the child is locked.
* @see lockChild()
*/
bool isChildLocked(Scene_interface::Item_id id);
//!Returns if the group_item is currently expanded or collapsed in the Geometric Objects list. //!Returns if the group_item is currently expanded or collapsed in the Geometric Objects list.
//! True means expanded, false means collapsed. //! True means expanded, false means collapsed.
//! @see isExpanded(). //! @see isExpanded().
@ -83,15 +103,15 @@ public :
//! @see isExpanded(). //! @see isExpanded().
void setExpanded(bool); void setExpanded(bool);
//!Returns an empty Bbox to avoid disturbing the Bbox of the scene. //!Returns an empty Bbox to avoid disturbing the Bbox of the scene.
Bbox bbox() const; Bbox bbox() const Q_DECL_OVERRIDE;
//!Not supported. //!Not supported.
Scene_item* clone() const {return 0;} Scene_item* clone() const Q_DECL_OVERRIDE {return 0;}
//! Indicates if the rendering mode is supported. //! Indicates if the rendering mode is supported.
//! \returns true for all rendering modes that are shared by //! \returns true for all rendering modes that are shared by
//! all of the children. //! all of the children.
bool supportsRenderingMode(RenderingMode m) const; bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE;
//!\returns a string containing the number of children. //!\returns a string containing the number of children.
QString toolTip() const; QString toolTip() const Q_DECL_OVERRIDE;
/// Draw functions /// Draw functions
/// Scene_group_item's children are not drawn by the scene, they are drawn by the group. /// Scene_group_item's children are not drawn by the scene, they are drawn by the group.
@ -102,32 +122,52 @@ public :
//! and `Scene_item::drawPoints` for each child if its current //! and `Scene_item::drawPoints` for each child if its current
//! rendering mode is adequat. //! rendering mode is adequat.
//! @see #RenderingMode //! @see #RenderingMode
virtual void draw(CGAL::Three::Viewer_interface*) const; virtual void draw(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE;
//!\brief draws all the children //!\brief draws all the children
//! //!
//! Calls `Scene_item::drawEdges()`, then calls `Scene_item::draw()` //! Calls `Scene_item::drawEdges()`, then calls `Scene_item::draw()`
//! and `Scene_item::drawPoints` for each child if its current //! and `Scene_item::drawPoints` for each child if its current
//! rendering mode is adequat. //! rendering mode is adequat.
//! @see #RenderingMode //! @see #RenderingMode
virtual void drawEdges(CGAL::Three::Viewer_interface*) const; virtual void drawEdges(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE;
//!\brief draws all the children //!\brief draws all the children
//! //!
//! Calls `Scene_item::drawPoints()`, then calls `Scene_item::draw()` //! Calls `Scene_item::drawPoints()`, then calls `Scene_item::draw()`
//! and `Scene_item::drawEdges()` for each child if its current //! and `Scene_item::drawEdges()` for each child if its current
//! rendering mode is adequat. //! rendering mode is adequat.
//! @see #RenderingMode //! @see #RenderingMode
virtual void drawPoints(CGAL::Three::Viewer_interface*) const; virtual void drawPoints(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE;
//!
//! \brief deals with the rendering, selecting and picking of
//! the group's children.
//!
//! \param picked_item_IDs the depth-index map
//! \param picked_pixel the screen point that has been picked.
//! \param with_names should be `true` if a picking is being performed.
//!
virtual void renderChildren(Viewer_interface *,
QMap<float, int>& picked_item_IDs, const QPoint &picked_pixel,
bool with_names);
///@} ///@}
//!Adds a CGAL::Three::Scene_item* to the list of children. //!Adds a CGAL::Three::Scene_item* to the list of children.
//!@see getChildren() @see removeChild() //!@see getChildren() @see removeChild()
void addChild(Scene_item* new_item); void addChild(Scene_item* new_item);
//!Adds a CGAL::Three::Scene_item* to the list of children from its id.
//! //!@see getChildren() @see removeChild()
void addChild(Scene_interface::Item_id new_id);
//! \brief getChild gives access to the Scene_item of the wanted index.
//! \returns the `CGAL::Three::Scene_item` which index is `id`.
//!
Scene_item* getChild(Scene_interface::Item_id id) { return scene->item(id);}
Scene_item* getChild(Scene_interface::Item_id id) const{ return scene->item(id);}
//!Sets all the children to the specified color. //!Sets all the children to the specified color.
void setColor(QColor c); void setColor(QColor c) Q_DECL_OVERRIDE;
//!Sets all the children in the specified rendering mode. //!Sets all the children in the specified rendering mode.
void setRenderingMode(RenderingMode m); void setRenderingMode(RenderingMode m) Q_DECL_OVERRIDE;
//!Sets all the children to the specified visibility. //!Sets all the children to the specified visibility.
void setVisible(bool b); void setVisible(bool b) Q_DECL_OVERRIDE;
//!Sets all the children in points mode. //!Sets all the children in points mode.
void setPointsMode() { void setPointsMode() {
setRenderingMode(Points); setRenderingMode(Points);
@ -160,11 +200,14 @@ public :
void setPointsPlusNormalsMode(){ void setPointsPlusNormalsMode(){
setRenderingMode(PointsPlusNormals); setRenderingMode(PointsPlusNormals);
} }
//!Sets the alpha value for the froup and all its children.
virtual void setAlpha(int) Q_DECL_OVERRIDE;
//! \brief Returns a list of all the direct children. //! \brief Returns a list of all the direct children.
//! //!
//! Only returns children that have this item as a parent. //! Only returns children that have this item as a parent.
//! Children of these children are not returned. //! Children of these children are not returned.
QList<Scene_item*> getChildren() const {return children;} QList<Scene_interface::Item_id> getChildren() const {return children;}
//! \brief getChildrenForSelection returns the list of //! \brief getChildrenForSelection returns the list of
//! children to select along with the group. //! children to select along with the group.
@ -173,7 +216,7 @@ public :
//! this function defines which of its children will be added too. //! this function defines which of its children will be added too.
//! Typically overriden to allow applying an operation from the //! Typically overriden to allow applying an operation from the
//! Operation menu only to the parent item and not to its children. //! Operation menu only to the parent item and not to its children.
virtual QList<Scene_item*> getChildrenForSelection() const {return children;} virtual QList<Scene_interface::Item_id> getChildrenForSelection() const {return children;}
//!Removes a Scene_item from the list of children. //!Removes a Scene_item from the list of children.
//!@see getChildren() @see addChild() //!@see getChildren() @see addChild()
void removeChild( Scene_item* item) void removeChild( Scene_item* item)
@ -182,7 +225,13 @@ public :
return; return;
update_group_number(item,0); update_group_number(item,0);
item->moveToGroup(0); item->moveToGroup(0);
children.removeOne(item); children.removeOne(scene->item_id(item));
}
//!Removes a Scene_item from the list of children using its index.
//!@see getChildren() @see addChild()
void removeChild( Scene_interface::Item_id id)
{
removeChild(scene->item(id));
} }
//!Moves a child up in the list. //!Moves a child up in the list.
void moveUp(int); void moveUp(int);
@ -199,13 +248,13 @@ public Q_SLOTS:
//! `draw()` function. //! `draw()` function.
void resetDraw() { already_drawn = false;} void resetDraw() { already_drawn = false;}
private: private:
void update_group_number(Scene_item*new_item, int n); void update_group_number(Scene_item* new_item, int n);
bool expanded; bool expanded;
mutable bool already_drawn; mutable bool already_drawn;
protected: protected:
Scene_interface *scene; Scene_interface *scene;
//!Contains a reference to all the children of this group. //!Contains a reference to all the children of this group.
QList<Scene_item*> children; QList<Scene_interface::Item_id> children;
}; //end of class Scene_group_item }; //end of class Scene_group_item

View File

@ -235,6 +235,15 @@ public:
//! the Operations menu, actions to save or clone the item if it is supported //! the Operations menu, actions to save or clone the item if it is supported
//! and any contextual action for the item. //! and any contextual action for the item.
virtual QMenu* contextMenu(); virtual QMenu* contextMenu();
//!
//! \brief setId informs the item of its current index in the scene entries.
//!
void setId(int id);
//!
//! \brief getId returns the current index of this item in the scene entries.
//!
int getId()const;
//!Handles key press events. //!Handles key press events.
virtual bool keyPressEvent(QKeyEvent*){return false;} virtual bool keyPressEvent(QKeyEvent*){return false;}
@ -354,7 +363,15 @@ public Q_SLOTS:
//!This might be needed as items are not always deleted right away by Qt and this behaviour may cause a simily //!This might be needed as items are not always deleted right away by Qt and this behaviour may cause a simily
//!memory leak, for example when multiple items are created at the same time. //!memory leak, for example when multiple items are created at the same time.
virtual void itemAboutToBeDestroyed(Scene_item*); virtual void itemAboutToBeDestroyed(Scene_item*);
//!Returns the alpha value for the item.
//! Must be called within a valid openGl context.
virtual float alpha() const;
//! Sets the value of the aplha Slider for this item.
//!
//! Must be overriden;
//! \param alpha must be between 0 and 255
virtual void setAlpha(int alpha);
//!Selects a point through raycasting. //!Selects a point through raycasting.
virtual void select(double orig_x, virtual void select(double orig_x,
double orig_y, double orig_y,
@ -432,6 +449,7 @@ protected:
/*! Contains the VAOs. /*! Contains the VAOs.
*/ */
std::vector<QOpenGLVertexArrayObject*> vaos; std::vector<QOpenGLVertexArrayObject*> vaos;
int cur_id;
//!Adds a VAO to the Map. //!Adds a VAO to the Map.
void addVaos(int i) void addVaos(int i)
{ {

View File

@ -37,6 +37,7 @@ class QImage;
class QMouseEvent; class QMouseEvent;
class QKeyEvent; class QKeyEvent;
class QOpenGLShaderProgram; class QOpenGLShaderProgram;
class QOpenGLFramebufferObject;
class TextRenderer; class TextRenderer;
class TextListItem; class TextListItem;
@ -213,6 +214,9 @@ public:
//! Returns the static image to be displayed in 2D selection mode. //! Returns the static image to be displayed in 2D selection mode.
virtual const QImage& staticImage() const = 0; virtual const QImage& staticImage() const = 0;
//!The number of passes that are performed for the scene transparency.
//! Customizable from the MainWindow or the SubViewer menu.
virtual float total_pass() = 0;
Q_SIGNALS: Q_SIGNALS:
//!Emit this to signal that the `id`th item has been picked. //!Emit this to signal that the `id`th item has been picked.
void selected(int id); void selected(int id);
@ -255,6 +259,13 @@ public:
//! @returns a pointer to an initialized QOpenGLFunctions_4_3_Compatibility if `isOpenGL_4_3()` is `true` //! @returns a pointer to an initialized QOpenGLFunctions_4_3_Compatibility if `isOpenGL_4_3()` is `true`
//! @returns NULL if `isOpenGL_4_3()` is `false` //! @returns NULL if `isOpenGL_4_3()` is `false`
virtual QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() = 0; virtual QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() = 0;
virtual void setCurrentPass(int pass) = 0;
virtual void setDepthWriting(bool writing_depth) = 0;
virtual void setDepthPeelingFbo(QOpenGLFramebufferObject* fbo) = 0;
virtual int currentPass()const = 0;
virtual bool isDepthWriting()const = 0;
virtual QOpenGLFramebufferObject* depthPeelingFbo() = 0;
}; // end class Viewer_interface }; // end class Viewer_interface
} }
} }