mirror of https://github.com/CGAL/cgal
Change the semantic of the Scene_group_item
New feature: an object of class `Scene_group_item`, or derived, is
responsible for drawing its children items. That is the first
approximation of a scene graph.
For that goal, several steps were needed.
- Remove the overload of `Scene::draw()` and `Scene::drawWithNames()`
that does not have the viewer as parameter. Remove then from
`Scene_draw_interface` as well.
- Add `Viewer::inDrawWithNames()` so that items, including the
`Scene_group_item`, can now if a draw function is called for the
picking or not.
- Add the draw function in `Scene_group_item`:
```
virtual void draw(CGAL::Three::Viewer_interface*) const;
virtual void draw_edges(CGAL::Three::Viewer_interface*) const;
virtual void draw_points(CGAL::Three::Viewer_interface*) const;
virtual void draw_splats(CGAL::Three::Viewer_interface*) const;
```
Those draw functions actually call the draw functions of all the
visible children, depending on their rendering mode. If
`viewer->inDrawWithNames()`, draw nothing, and let the children be
drawn with their own names. Another solution could be that the draw
functions of `Scene_group_item` use `glPushName/glPopName`. That API
seems to be usable with a scene graph.
- Add in `Scene_item` two functions:
```
void moveToGroup(Scene_group_item* group);
Scene_group_item* parentGroup() const;
```
That is one first step to allow the `has_group` data member to become
a private member, instead a public one (ugly!!).
Then the big change is in the scene:
- The scene will not call the draw function of items with a parent
group, if the group itself is visible. If the group is not visible but
the children are set to visible, then they are drawn anyway. That
means that a group can "steal" the drawing of its children when it is
visible. That behavior is really convenient for the use case I have in
mind, but it may be strange.
- In the picking, in `drawWithName()`, the draw function of all items
are called, even if they have a parent group.
Cosmetic:
- Move the definition of the constructor `Scene_item::Scene_item` in
the cpp file.
This commit is contained in:
parent
96c4dc60de
commit
80d7a738e4
|
|
@ -311,27 +311,28 @@ Scene::keyPressEvent(QKeyEvent* e){
|
|||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
Scene::draw()
|
||||
{
|
||||
draw_aux(false, 0);
|
||||
}
|
||||
void
|
||||
Scene::draw(CGAL::Three::Viewer_interface* viewer)
|
||||
{
|
||||
draw_aux(false, viewer);
|
||||
}
|
||||
void
|
||||
Scene::drawWithNames()
|
||||
{
|
||||
draw_aux(true, 0);
|
||||
}
|
||||
void
|
||||
Scene::drawWithNames(CGAL::Three::Viewer_interface* viewer)
|
||||
{
|
||||
draw_aux(true, viewer);
|
||||
}
|
||||
|
||||
bool item_should_be_skipped_in_draw(Scene_item* item) {
|
||||
if(!item->visible()) return true;
|
||||
if(item->has_group == 0) return false;
|
||||
Scene_group_item* group = item->parentGroup();
|
||||
while(group != 0) {
|
||||
if(!group->visible()) return false;
|
||||
group = group->parentGroup();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
|
||||
{
|
||||
|
|
@ -342,10 +343,12 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
|
|||
// Flat/Gouraud OpenGL drawing
|
||||
for(int index = 0; index < m_entries.size(); ++index)
|
||||
{
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(with_names) {
|
||||
viewer->glPushName(index);
|
||||
} else {
|
||||
if(item_should_be_skipped_in_draw(&item)) continue;
|
||||
}
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(item.visible())
|
||||
{
|
||||
if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud)
|
||||
|
|
@ -378,14 +381,17 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
|
|||
viewer->glPopName();
|
||||
}
|
||||
}
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
// Wireframe OpenGL drawing
|
||||
for(int index = 0; index < m_entries.size(); ++index)
|
||||
{
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(with_names) {
|
||||
viewer->glPushName(index);
|
||||
}
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
else {
|
||||
if(item_should_be_skipped_in_draw(&item)) continue;
|
||||
}
|
||||
if(item.visible())
|
||||
{
|
||||
if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe)
|
||||
|
|
@ -442,10 +448,12 @@ glDepthFunc(GL_LEQUAL);
|
|||
// Points OpenGL drawing
|
||||
for(int index = 0; index < m_entries.size(); ++index)
|
||||
{
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(with_names) {
|
||||
viewer->glPushName(index);
|
||||
} else {
|
||||
if(item_should_be_skipped_in_draw(&item)) continue;
|
||||
}
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(item.visible())
|
||||
{
|
||||
if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals)
|
||||
|
|
@ -474,6 +482,7 @@ glDepthFunc(GL_LEQUAL);
|
|||
for(int index = 0; index < m_entries.size(); ++index)
|
||||
{
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(item_should_be_skipped_in_draw(&item)) continue;
|
||||
if(item.visible() && item.renderingMode() == Splatting)
|
||||
{
|
||||
|
||||
|
|
@ -486,9 +495,11 @@ glDepthFunc(GL_LEQUAL);
|
|||
}
|
||||
|
||||
}
|
||||
ms_splatting->beginAttributePass();
|
||||
for(int index = 0; index < m_entries.size(); ++index)
|
||||
{ CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
ms_splatting->beginAttributePass();
|
||||
for(int index = 0; index < m_entries.size(); ++index)
|
||||
{
|
||||
CGAL::Three::Scene_item& item = *m_entries[index];
|
||||
if(item_should_be_skipped_in_draw(&item)) continue;
|
||||
if(item.visible() && item.renderingMode() == Splatting)
|
||||
{
|
||||
viewer->glColor4d(item.color().redF(), item.color().greenF(), item.color().blueF(), item.color().alphaF());
|
||||
|
|
@ -1077,7 +1088,7 @@ void Scene::changeGroup(Scene_item *item, CGAL::Three::Scene_group_item *target_
|
|||
}
|
||||
//add the item to the target group
|
||||
target_group->addChild(item);
|
||||
item->has_group = target_group->has_group +1;
|
||||
item->moveToGroup(target_group);
|
||||
}
|
||||
|
||||
float Scene::get_bbox_length() const
|
||||
|
|
|
|||
|
|
@ -110,10 +110,6 @@ public:
|
|||
* of OpenGL code that needs a context.
|
||||
*/
|
||||
void initializeGL();
|
||||
/*! Is called by Viewer::draw(). Is deprecated and does nothing.*/
|
||||
void draw();
|
||||
/*! Is deprecated and does nothing.*/
|
||||
void drawWithNames();
|
||||
/*! Is called by Viewer::draw(Viewer_interface*). Calls draw_aux(false, viewer).
|
||||
* @see draw_aux(bool with_names, Viewer_interface).*/
|
||||
void draw(CGAL::Three::Viewer_interface*);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#include <CGAL/Three/Scene_group_item.h>
|
||||
#include <CGAL/Three/Viewer_interface.h>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace CGAL::Three;
|
||||
|
|
@ -114,3 +114,55 @@ void Scene_group_item::moveUp(int i)
|
|||
{
|
||||
children.move(i, i-1);
|
||||
}
|
||||
|
||||
void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
|
||||
if(viewer->inDrawWithNames()) return;
|
||||
Q_FOREACH(Scene_item* child, children) {
|
||||
if(!child->visible()) continue;
|
||||
switch(child->renderingMode()) {
|
||||
case Flat:
|
||||
case FlatPlusEdges:
|
||||
case Gouraud:
|
||||
child->draw(viewer); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene_group_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const
|
||||
{
|
||||
if(viewer->inDrawWithNames()) return;
|
||||
Q_FOREACH(Scene_item* child, children) {
|
||||
if(!child->visible()) continue;
|
||||
switch(child->renderingMode()) {
|
||||
case FlatPlusEdges:
|
||||
case Wireframe:
|
||||
case PointsPlusNormals:
|
||||
child->draw_edges(viewer); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene_group_item::draw_points(CGAL::Three::Viewer_interface* viewer) const
|
||||
{
|
||||
if(viewer->inDrawWithNames()) return;
|
||||
Q_FOREACH(Scene_item* child, children) {
|
||||
if(!child->visible()) continue;
|
||||
switch(child->renderingMode()) {
|
||||
case Points:
|
||||
case PointsPlusNormals:
|
||||
child->draw_points(viewer); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene_group_item::draw_splats(CGAL::Three::Viewer_interface* viewer) const
|
||||
{
|
||||
if(viewer->inDrawWithNames()) return;
|
||||
Q_FOREACH(Scene_item* child, children) {
|
||||
if(child->visible() && child->renderingMode() == Splatting)
|
||||
child->draw_splats(viewer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <CGAL/Three/Scene_item.h>
|
||||
#include <CGAL/Three/Scene_group_item.h>
|
||||
#include <CGAL/Three/Scene_interface.h>
|
||||
#include <QMenu>
|
||||
#include <iostream>
|
||||
|
|
@ -6,6 +7,37 @@
|
|||
#include <CGAL/Three/Viewer_interface.h>
|
||||
const QColor CGAL::Three::Scene_item::defaultColor = QColor(100, 100, 255);
|
||||
|
||||
CGAL::Three::Scene_item::Scene_item(int buffers_size, int vaos_size)
|
||||
: name_("unamed"),
|
||||
color_(defaultColor),
|
||||
visible_(true),
|
||||
are_buffers_filled(false),
|
||||
rendering_mode(FlatPlusEdges),
|
||||
defaultContextMenu(0),
|
||||
buffersSize(buffers_size),
|
||||
vaosSize(vaos_size),
|
||||
vaos(vaos_size)
|
||||
{
|
||||
is_bbox_computed = false;
|
||||
is_monochrome = true;
|
||||
for(int i=0; i<vaosSize; i++)
|
||||
{
|
||||
addVaos(i);
|
||||
vaos[i]->create();
|
||||
}
|
||||
|
||||
buffers.reserve(buffersSize);
|
||||
for(int i=0; i<buffersSize; i++)
|
||||
{
|
||||
QOpenGLBuffer n_buf;
|
||||
buffers.push_back(n_buf);
|
||||
buffers[i].create();
|
||||
}
|
||||
nb_isolated_vertices = 0;
|
||||
has_group = 0;
|
||||
parent_group = 0;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item::~Scene_item() {
|
||||
delete defaultContextMenu;
|
||||
for(int i=0; i<buffersSize; i++)
|
||||
|
|
@ -101,6 +133,19 @@ QMenu* CGAL::Three::Scene_item::contextMenu()
|
|||
return defaultContextMenu;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_group_item* CGAL::Three::Scene_item::parentGroup() const {
|
||||
return parent_group;
|
||||
}
|
||||
|
||||
void CGAL::Three::Scene_item::
|
||||
moveToGroup(CGAL::Three::Scene_group_item* group) {
|
||||
parent_group = group;
|
||||
if(group)
|
||||
has_group = group->has_group + 1;
|
||||
else
|
||||
has_group = 0;
|
||||
}
|
||||
|
||||
void CGAL::Three::Scene_item::invalidateOpenGLBuffers() {}
|
||||
|
||||
void CGAL::Three::Scene_item::selection_changed(bool) {}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public:
|
|||
bool twosides;
|
||||
bool macro_mode;
|
||||
bool inFastDrawing;
|
||||
bool inDrawWithNames;
|
||||
|
||||
void draw_aux(bool with_names, Viewer*);
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ Viewer::Viewer(QWidget* parent, bool antialiasing)
|
|||
d->twosides = false;
|
||||
d->macro_mode = false;
|
||||
d->inFastDrawing = true;
|
||||
d->inDrawWithNames = false;
|
||||
d->shader_programs.resize(NB_OF_PROGRAMS);
|
||||
setShortcut(EXIT_VIEWER, 0);
|
||||
setShortcut(DRAW_AXIS, 0);
|
||||
|
|
@ -321,6 +323,7 @@ void Viewer_impl::draw_aux(bool with_names, Viewer* viewer)
|
|||
viewer->glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
|
||||
viewer->glBlendFunc(GL_ONE, GL_ZERO);
|
||||
}
|
||||
inDrawWithNames = with_names;
|
||||
if(with_names)
|
||||
scene->drawWithNames(viewer);
|
||||
else
|
||||
|
|
@ -329,6 +332,10 @@ void Viewer_impl::draw_aux(bool with_names, Viewer* viewer)
|
|||
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
}
|
||||
|
||||
bool Viewer::inDrawWithNames() const {
|
||||
return d->inDrawWithNames;
|
||||
}
|
||||
|
||||
void Viewer::drawWithNames()
|
||||
{
|
||||
QGLViewer::draw();
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ public:
|
|||
bool antiAliasing() const;
|
||||
//! @returns the fastDrawing state.
|
||||
bool inFastDrawing() const;
|
||||
//! Implementation of `Viewer_interface::inDrawWithNames()`
|
||||
bool inDrawWithNames() const;
|
||||
//! Implementation of `Viewer_interface::attrib_buffers()`
|
||||
void attrib_buffers(int program_name) const;
|
||||
//! Implementation of `Viewer_interface::getShaderProgram()`
|
||||
|
|
|
|||
|
|
@ -33,10 +33,8 @@ class Scene_draw_interface {
|
|||
public:
|
||||
virtual ~Scene_draw_interface(){}
|
||||
virtual void initializeGL() = 0;
|
||||
virtual void draw() = 0;
|
||||
virtual void draw(CGAL::Three::Viewer_interface*) { draw(); };
|
||||
virtual void drawWithNames() = 0;
|
||||
virtual void drawWithNames(CGAL::Three::Viewer_interface*) { drawWithNames(); }
|
||||
virtual void draw(CGAL::Three::Viewer_interface*) = 0;
|
||||
virtual void drawWithNames(CGAL::Three::Viewer_interface*) = 0;
|
||||
virtual bool keyPressEvent(QKeyEvent* e) = 0;
|
||||
virtual float get_bbox_length() const = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,6 +62,15 @@ public :
|
|||
bool supportsRenderingMode(RenderingMode m) const;
|
||||
//!Prints the number of children.
|
||||
QString toolTip() const;
|
||||
|
||||
/// Draw functions
|
||||
///@{
|
||||
virtual void draw(CGAL::Three::Viewer_interface*) const;
|
||||
virtual void draw_edges(CGAL::Three::Viewer_interface*) const;
|
||||
virtual void draw_points(CGAL::Three::Viewer_interface*) const;
|
||||
virtual void draw_splats(CGAL::Three::Viewer_interface*) const;
|
||||
///@}
|
||||
|
||||
//!Adds a Scene_item* to the list of children.
|
||||
//!@see getChildren. @see removeChild.
|
||||
void addChild(Scene_item* new_item);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class QKeyEvent;
|
|||
namespace CGAL {
|
||||
namespace Three {
|
||||
|
||||
class Scene_group_item;
|
||||
class Viewer_interface;
|
||||
//! This class represents an object in the OpenGL scene
|
||||
class SCENE_ITEM_EXPORT Scene_item : public QObject {
|
||||
|
|
@ -78,72 +79,12 @@ public:
|
|||
//! The default color of a scene_item.
|
||||
static const QColor defaultColor; // defined in Scene_item.cpp
|
||||
|
||||
//!The default Constructor.
|
||||
/*!
|
||||
* Initializes the number of VBOs to 20 and VAOs to 10 and creates them.
|
||||
*/
|
||||
Scene_item()
|
||||
: name_("unamed"),
|
||||
color_(defaultColor),
|
||||
visible_(true),
|
||||
are_buffers_filled(false),
|
||||
rendering_mode(FlatPlusEdges),
|
||||
defaultContextMenu(0),
|
||||
buffersSize(20),
|
||||
vaosSize(10),
|
||||
vaos(10)
|
||||
{
|
||||
is_bbox_computed = false;
|
||||
is_monochrome = true;
|
||||
for(int i=0; i<vaosSize; i++)
|
||||
{
|
||||
addVaos(i);
|
||||
vaos[i]->create();
|
||||
}
|
||||
|
||||
buffers.reserve(buffersSize);
|
||||
for(int i=0; i<buffersSize; i++)
|
||||
{
|
||||
QOpenGLBuffer n_buf;
|
||||
buffers.push_back(n_buf);
|
||||
buffers[i].create();
|
||||
}
|
||||
nb_isolated_vertices = 0;
|
||||
has_group = 0;
|
||||
}
|
||||
//!The Constructor.
|
||||
/*!
|
||||
* Initializes the number of VBOs and VAOs and creates them.
|
||||
*/
|
||||
Scene_item(int buffers_size, int vaos_size)
|
||||
: name_("unamed"),
|
||||
color_(defaultColor),
|
||||
visible_(true),
|
||||
are_buffers_filled(false),
|
||||
rendering_mode(FlatPlusEdges),
|
||||
defaultContextMenu(0),
|
||||
buffersSize(buffers_size),
|
||||
vaosSize(vaos_size),
|
||||
vaos(vaos_size)
|
||||
{
|
||||
is_bbox_computed = false;
|
||||
is_monochrome = true;
|
||||
for(int i=0; i<vaosSize; i++)
|
||||
{
|
||||
addVaos(i);
|
||||
vaos[i]->create();
|
||||
}
|
||||
Scene_item(int buffers_size = 20, int vaos_size = 10);
|
||||
|
||||
buffers.reserve(buffersSize);
|
||||
for(int i=0; i<buffersSize; i++)
|
||||
{
|
||||
QOpenGLBuffer n_buf;
|
||||
buffers.push_back(n_buf);
|
||||
buffers[i].create();
|
||||
}
|
||||
nb_isolated_vertices = 0;
|
||||
has_group = 0;
|
||||
}
|
||||
//! Setter for the number of isolated vertices.
|
||||
void setNbIsolatedvertices(std::size_t nb) { nb_isolated_vertices = nb;}
|
||||
//! Getter for the number of isolated vertices.
|
||||
|
|
@ -243,6 +184,9 @@ public:
|
|||
//!Handles key press events.
|
||||
virtual bool keyPressEvent(QKeyEvent*){return false;}
|
||||
|
||||
//!The parent group, or 0 if the item is not in a group.
|
||||
Scene_group_item* parentGroup() const;
|
||||
|
||||
//!Contains the header for the table in the statistics dialog
|
||||
/*!
|
||||
* A header data is composed of 2 columns : the Categories and the titles.
|
||||
|
|
@ -306,6 +250,10 @@ public Q_SLOTS:
|
|||
virtual void setName(QString n) { name_ = n; }
|
||||
//!Setter for the visibility of the item.
|
||||
virtual void setVisible(bool b) { visible_ = b; }
|
||||
//!Set the parent group. If `group==0`, then the item has no parent.
|
||||
//!This function is called by `Scene::changeGroup` and should not be
|
||||
//!called manually.
|
||||
virtual void moveToGroup(Scene_group_item* group);
|
||||
//!Setter for the rendering mode of the item.
|
||||
//!@see RenderingMode
|
||||
virtual void setRenderingMode(RenderingMode m) {
|
||||
|
|
@ -378,6 +326,8 @@ protected:
|
|||
QColor color_;
|
||||
//!The visibility of the item.
|
||||
bool visible_;
|
||||
//!The parent group, or 0 if the item is not in a group.
|
||||
Scene_group_item* parent_group;
|
||||
//!Specifies if the item is currently selected.
|
||||
bool is_selected;
|
||||
//! Specifies if the item is monochrome and uses uniform attribute for its color
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ public:
|
|||
static QString dumpFrame(const qglviewer::Frame&);
|
||||
//! @returns the fastDrawing state.
|
||||
virtual bool inFastDrawing() const = 0;
|
||||
//! @returns if the viewer is in `drawWithNames()`
|
||||
virtual bool inDrawWithNames() const = 0;
|
||||
|
||||
/*! Passes all the uniform data to the shaders.
|
||||
* According to program_name, this data may change.
|
||||
|
|
|
|||
Loading…
Reference in New Issue