Merge branch 'Polyhedron_demo-Hierarchic_view-GF-old' into Polyhedron_demo-Hierarchic_view-GF

Conflicts:
	Polyhedron/demo/Polyhedron/CMakeLists.txt
	Polyhedron/demo/Polyhedron/MainWindow.cpp
	Polyhedron/demo/Polyhedron/Scene.cpp
	Polyhedron/demo/Polyhedron/Scene.h
This commit is contained in:
Maxime Gimeno 2015-11-23 09:32:20 +01:00
commit 7ad45de6ef
17 changed files with 1087 additions and 140 deletions

View File

@ -0,0 +1,111 @@
#ifndef SCENE_INTERFACE_H
#define SCENE_INTERFACE_H
#include <QString>
#include <QColor>
#include <QList>
#include <algorithm>
#include <cmath>
class Scene_item;
// OpenGL rendering mode
enum RenderingMode { Points = 0,
PointsPlusNormals,
Splatting,
Wireframe,
Flat,
FlatPlusEdges,
Gouraud,
LastRenderingMode = Gouraud,
NumberOfRenderingMode = LastRenderingMode+1 };
// Interface of Scene class exported to plugins
class Scene_interface {
public:
struct Bbox {
double xmin, ymin, zmin;
double xmax, ymax, zmax;
Bbox(const double _xmin,const double _ymin,const double _zmin,
const double _xmax,const double _ymax,const double _zmax)
: xmin(_xmin), ymin(_ymin), zmin(_zmin),
xmax(_xmax), ymax(_ymax), zmax(_zmax)
{
}
Bbox()
: xmin(0.0), ymin(0.0), zmin(0.0),
xmax(1.0), ymax(1.0), zmax(1.0)
{
}
Bbox operator+(const Bbox& b) const {
return Bbox((std::min)(xmin, b.xmin),
(std::min)(ymin, b.ymin),
(std::min)(zmin, b.zmin),
(std::max)(xmax, b.xmax),
(std::max)(ymax, b.ymax),
(std::max)(zmax, b.zmax));
}
bool operator==(const Bbox&b) const{
return
xmin==b.xmin && xmax==b.xmax &&
ymin==b.ymin && ymax==b.ymax &&
zmin==b.zmin && zmax==b.zmax;
}
bool operator!=(const Bbox& b) const{
return !(*this == b);
}
double width() const { return xmax-xmin; }
double height() const { return ymax-ymin; }
double depth() const { return zmax-zmin; }
double diagonal_length() const
{
return std::sqrt(width()*width() + height()*height() + depth()*depth());
}
}; // struct BBox (ad hoc class, does not depend on CGAL kernels
typedef int Item_id;
virtual ~Scene_interface() {}
virtual Item_id addItem(Scene_item* item) = 0;
virtual Scene_item* replaceItem(Item_id, Scene_item*, bool emit_item_about_to_be_destroyed = false) = 0;
virtual Item_id erase(Item_id) = 0;
// Returns the index of the item just before the one that is erased,
// or just after. Returns -1 if the list is empty.
virtual Item_id duplicate(Item_id) = 0;
// Returns the index of the new item
// If no new item has been created (because the item type is note
// clonable), returns -1.
// Accessors (getters)
virtual int numberOfEntries() const = 0;
virtual Scene_item* item(Item_id) const = 0;
virtual Item_id item_id(Scene_item*) const = 0;
virtual Item_id mainSelectionIndex() const = 0;
virtual QList<Item_id> selectionIndices() const = 0;
virtual Item_id selectionAindex() const = 0;
virtual Item_id selectionBindex() const = 0;
// Get scene bounding box
virtual Bbox bbox() const = 0;
virtual double len_diagonal() const = 0;
public:
// Notify the scene that an item was modified
virtual void itemChanged(Item_id i) = 0;
virtual void itemChanged(Scene_item*) = 0;
// Select an item
virtual void setSelectedItem(Item_id) = 0;
}; // end interface Scene_interface
#endif // SCENE_INTERFACE_H

View File

@ -142,6 +142,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
Viewer_interface_moc.cpp
Scene_item_moc.cpp
Scene_item.cpp #Scene_item.moc
Scene_group_item.cpp
Polyhedron_demo_plugin_helper.cpp)
qt5_use_modules(demo_framework OpenGL Gui Widgets Script Xml)
@ -222,7 +223,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
scene_basic_objects
scene_polyhedron_item
scene_polygon_soup_item
scene_nef_polyhedron_item )
scene_nef_polyhedron_item)
add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${lib} )
endforeach()
@ -264,8 +265,9 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
FOREACH(SUB_DIR ${DEMO_PLUGINS})
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/${SUB_DIR}")
ENDFOREACH()
add_executable(example_plugin IMPORTED)
set_property(TARGET example_plugin PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/../../../Example_plugin/example_plugin.cmake")
add_item(scene_group_item Scene_group_item.cpp)
polyhedron_demo_plugin(group_plugin Polyhedron_demo_group_plugin ${groupUI_FILES})
target_link_libraries(group_plugin scene_group_item)
#
# Exporting
#

View File

@ -116,7 +116,6 @@ MainWindow::~MainWindow()
{
delete ui;
}
MainWindow::MainWindow(QWidget* parent)
: CGAL::Qt::DemosMainWindow(parent)
{
@ -146,17 +145,21 @@ MainWindow::MainWindow(QWidget* parent)
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(scene);
SceneDelegate *delegate = new SceneDelegate(this);
delegate->setProxy(proxyModel);
delegate->setScene(scene);
connect(ui->searchEdit, SIGNAL(textChanged(QString)),
proxyModel, SLOT(setFilterFixedString(QString)));
sceneView->setModel(proxyModel);
// setup the sceneview: delegation and columns sizing...
sceneView->setItemDelegate(new SceneDelegate(this));
sceneView->setItemDelegate(delegate);
sceneView->header()->setStretchLastSection(false);
sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch);
sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch);
//sceneView->header()->setStretchLastSection(false);
/* sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch);
sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch);
sceneView->header()->setSectionResizeMode(Scene::ColorColumn, QHeaderView::ResizeToContents);
sceneView->header()->setSectionResizeMode(Scene::RenderingModeColumn, QHeaderView::Fixed);
sceneView->header()->setSectionResizeMode(Scene::ABColumn, QHeaderView::Fixed);
@ -165,7 +168,7 @@ MainWindow::MainWindow(QWidget* parent)
sceneView->resizeColumnToContents(Scene::RenderingModeColumn);
sceneView->resizeColumnToContents(Scene::ABColumn);
sceneView->resizeColumnToContents(Scene::VisibleColumn);
*/
// setup connections
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
this, SLOT(updateInfo()));
@ -207,6 +210,15 @@ MainWindow::MainWindow(QWidget* parent)
connect(sceneView, SIGNAL(customContextMenuRequested(const QPoint & )),
this, SLOT(showSceneContextMenu(const QPoint &)));
connect(sceneView, SIGNAL(expanded(QModelIndex)),
scene, SLOT(setExpanded(QModelIndex)));
connect(sceneView, SIGNAL(collapsed(QModelIndex)),
scene, SLOT(setCollapsed(QModelIndex)));
connect(scene, SIGNAL(restoreCollapsedState()),
this, SLOT(restoreCollapseState()));
connect(viewer, SIGNAL(selected(int)),
this, SLOT(selectSceneItem(int)));
connect(viewer, SIGNAL(selectedPoint(double, double, double)),
@ -999,6 +1011,7 @@ void MainWindow::selectSceneItem(int i)
else {
QItemSelection s =
proxyModel->mapSelectionFromSource(scene->createSelection(i));
sceneView->selectionModel()->select(s,
QItemSelectionModel::ClearAndSelect);
}
@ -1053,21 +1066,24 @@ void MainWindow::selectAll()
int MainWindow::getSelectedSceneItemIndex() const
{
QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows();
if(selectedRows.size() != 1)
QModelIndexList selectedRows = sceneView->selectionModel()->selectedIndexes();
if(selectedRows.size() != 5)
return -1;
else {
QModelIndex i = proxyModel->mapToSource(selectedRows.first());
return i.row();
return scene->getIdFromModelIndex(i);
}
}
QList<int> MainWindow::getSelectedSceneItemIndices() const
{
QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows();
QModelIndexList selectedIndices = sceneView->selectionModel()->selectedIndexes();
QList<int> result;
Q_FOREACH(QModelIndex index, selectedRows) {
result << proxyModel->mapToSource(index).row();
Q_FOREACH(QModelIndex index, selectedIndices) {
int temp = scene->getIdFromModelIndex(proxyModel->mapToSource(index));
if(!result.contains(temp))
result<<temp;
}
return result;
}
@ -1110,7 +1126,7 @@ void MainWindow::contextMenuRequested(const QPoint& global_pos) {
void MainWindow::showSceneContextMenu(int selectedItemIndex,
const QPoint& global_pos)
{
CGAL::Three::Scene_item* item = scene->item(selectedItemIndex);
CGAL::Three::Scene_item* item = scene->item(scene->getIdFromModelIndex(scene->index(selectedItemIndex,0,QModelIndex())));
if(!item) return;
const char* prop_name = "Menu modified by MainWindow.";
@ -1149,10 +1165,24 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
int index = -1;
if(sender == sceneView) {
QModelIndex modelIndex = sceneView->indexAt(p);
if(!modelIndex.isValid()) return;
QModelIndex modelIndex = sceneView->indexAt(p);
if(!modelIndex.isValid())
{
const char* prop_name = "Menu modified by MainWindow.";
index = proxyModel->mapToSource(modelIndex).row();
QMenu* menu = ui->menuFile;
if(menu) {
bool menuChanged = menu->property(prop_name).toBool();
if(!menuChanged) {
menu->setProperty(prop_name, true);
}
}
if(menu)
menu->exec(sender->mapToGlobal(p));
return;
}
else
index = proxyModel->mapToSource(modelIndex).row();
}
else {
index = scene->mainSelectionIndex();
@ -1188,7 +1218,7 @@ void MainWindow::updateInfo() {
}
ui->infoLabel->setText(item_text);
}
else
else
ui->infoLabel->clear();
}
@ -1617,5 +1647,35 @@ Q_FOREACH(QAction* a, as)
ui->menuOperations->clear();
ui->menuOperations->addActions(as);
}
}
void MainWindow::recurseExpand(QModelIndex index)
{
int row = index.row();
if(index.child(0,0).isValid())
{
recurseExpand(index.child(0,0));
}
QString name = scene->item(scene->getIdFromModelIndex(index))->name();
Scene_group_item* group =
qobject_cast<Scene_group_item*>(scene->item(scene->getIdFromModelIndex(index)));
if(group && group->isExpanded())
{
sceneView->setExpanded(proxyModel->mapFromSource(index), true);
}
else if (group && !group->isExpanded()){
sceneView->setExpanded(proxyModel->mapFromSource(index), false);
}
if( index.sibling(row+1,0).isValid())
recurseExpand(index.sibling(row+1,0));
}
void MainWindow::restoreCollapseState()
{
QModelIndex modelIndex = scene->index(0,0,scene->invisibleRootItem()->index());
if(modelIndex.isValid())
recurseExpand(modelIndex);
}

View File

@ -28,6 +28,7 @@ class Scene_item;
}
class QSortFilterProxyModel;
class QModelIndex;
namespace Ui {
class MainWindow;
@ -72,7 +73,8 @@ public Q_SLOTS:
void updateViewerBBox();
void open(QString);
//! given an extension file, returns true if `filename` matches the filter
void restoreCollapseState();
/// given a file extension file, returns true if `filename` matches the filter
bool file_matches_filter(const QString& filters, const QString& filename);
/*! Open a file with a given loader, and return true if it was successful.
@ -328,6 +330,7 @@ protected:
QList<int> getSelectedSceneItemIndices() const;
private:
void recurseExpand(QModelIndex index);
QString strippedName(const QString &fullFileName);
void setMenus(QString, QString, QAction *a);
/// plugin black-list

View File

@ -201,6 +201,9 @@
<property name="editTriggers">
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
@ -208,7 +211,7 @@
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="indentation">
<number>0</number>
<number>10</number>
</property>
</widget>
</item>

View File

@ -13,6 +13,7 @@ Scene_polyhedron_transform_item::Scene_polyhedron_transform_item(const qglviewer
{
frame->setPosition(pos);
nb_lines = 0;
invalidate_buffers();
}
void Scene_polyhedron_transform_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer =0) const
@ -33,6 +34,7 @@ void Scene_polyhedron_transform_item::initialize_buffers(CGAL::Three::Viewer_int
QColor color = this->color();
program->setAttributeValue("colors",color);
vaos[Edges]->release();
program->release();
}
nb_lines = positions_lines.size();
@ -64,7 +66,6 @@ void Scene_polyhedron_transform_item::compute_elements() const
positions_lines.push_back(b.z()-center_.z);
}
}
void Scene_polyhedron_transform_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const
@ -79,6 +80,8 @@ void Scene_polyhedron_transform_item::draw_edges(CGAL::Three::Viewer_interface*
for (int i=0; i<16; ++i){
f_matrix.data()[i] = (float)frame->matrix()[i];
}
QColor color = this->color();
program->setAttributeValue("colors",color);
program->setUniformValue("f_matrix", f_matrix);
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(nb_lines/3));
vaos[Edges]->release();

View File

@ -0,0 +1,50 @@
#include "Polyhedron_demo_group_plugin.h"
#include "Polyhedron_demo_group_plugin.moc"
#include "Scene.h"
#include <QMenu>
/****************
* Group Plugin *
****************/
void Polyhedron_demo_group_plugin::init(QMainWindow* mainWindow,
CGAL::Three::Scene_interface* scene_interface,Messages_interface* m ) {
//get the references
trueScene = dynamic_cast<Scene*>(scene_interface);
this->scene = scene_interface;
this->mw = mainWindow;
messages = m;
//creates and link the actions
actionAddToGroup= new QAction("Add new group", mw);
if(actionAddToGroup) {
connect(actionAddToGroup, SIGNAL(triggered()),
this, SLOT(add_group()));
}
QMenu* menuFile = mw->findChild<QMenu*>("menuFile");
if ( NULL != menuFile )
{
QList<QAction*> menuFileActions = menuFile->actions();
// Look for action just after "Load..." action
QAction* actionAfterLoad = NULL;
for ( QList<QAction*>::iterator it_action = menuFileActions.begin(),
end = menuFileActions.end() ; it_action != end ; ++ it_action ) //Q_FOREACH( QAction* action, menuFileActions)
{
if ( NULL != *it_action && (*it_action)->text().contains("Load") )
{
++it_action;
if ( it_action != end && NULL != *it_action )
{
actionAfterLoad = *it_action;
}
}
}
// Insert "Load implicit function" action
if ( NULL != actionAfterLoad )
{
menuFile->insertAction(actionAfterLoad,actionAddToGroup);
}
}
}

View File

@ -0,0 +1,110 @@
#ifndef POLYHEDRON_DEMO_GROUP_H
#define POLYHEDRON_DEMO_GROUP_H
#include <QApplication>
#include <QMainWindow>
#include <QAction>
#include <QList>
#include "Scene_group_item.h"
#include "CGAL/Three/Scene_interface.h"
#include "Scene.h"
class Scene_interface;
#include "CGAL/Three/Polyhedron_demo_plugin_helper.h"
class Polyhedron_demo_group_plugin :
public QObject,
public CGAL::Three::Polyhedron_demo_plugin_helper
{
//Configures CMake to use MOC correctly
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public :
// To silent a warning -Woverloaded-virtual
// See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings
using Polyhedron_demo_plugin_helper::init;
void init(QMainWindow* mw, CGAL::Three::Scene_interface* sc, Messages_interface*);
bool applicable(QAction*) const
{
return true;
}
Scene* trueScene;
public Q_SLOTS:
void add_group() {
//Find the indices of the selected items
QList<int> indices;
QList<int> blacklist;
Q_FOREACH(int id, scene->selectionIndices()){
Scene_group_item* group =
qobject_cast<Scene_group_item*>(trueScene->item(id));
if(group)
Q_FOREACH(Scene_item *item, group->getChildren())
blacklist<<trueScene->item_id(item);
if(!indices.contains(id) && !blacklist.contains(id))
indices<<id;
}
//checks if all the selected items are in the same group
bool all_in_one = true;
if(indices.isEmpty())
all_in_one = false;
// new group to create
Scene_group_item * group = new Scene_group_item("new group");
//group containing the selected item
Scene_group_item * existing_group = 0;
//for each selected item
Q_FOREACH(int id, indices){
//if the selected item is in a group
if(trueScene->item(id)->has_group!=0){
//for each group
Q_FOREACH(Scene_group_item *item, trueScene->group_entries())
{
//if the group contains the selected item
if(item->getChildren().contains(trueScene->item(id))){
//if it is the first one, we initialize existing_group
if(existing_group == 0)
existing_group = item;
//else we check if it is the same group as before.
//If not, all selected items are not in the same group
else if(existing_group != item)
all_in_one = false;
break;
}
}//end for each group
}
//else it is impossible that all the selected items are in the same group
else{
all_in_one = false;
break;
}
}//end foreach selected item
//If all the selected items are in the same group, we put them in a sub_group of this group
if(all_in_one)
{
Q_FOREACH(int id, indices)
trueScene->changeGroup(trueScene->item(id),group);
trueScene->changeGroup(group, existing_group);
scene->addItem(group);
trueScene->group_added();
}
//else wer create a new group
else
{
Q_FOREACH(int id, indices)
trueScene->changeGroup(trueScene->item(id),group);
scene->addItem(group);
trueScene->group_added();
}
}
private:
QAction* actionAddToGroup;
void print_message(QString message) { messages->information(message); }
Messages_interface* messages;
}; //end of class Polyhedron_demo_group_plugin
#endif

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GroupDialog</class>
<widget class="QDialog" name="GroupDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>30</x>
<y>240</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>371</width>
<height>211</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="itemsView"/>
</item>
<item>
<widget class="QListView" name="groupsView"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GroupDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GroupDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,65 @@
#ifndef POLYHEDRON_DEMO_OPERATION_HELPER_H
#define POLYHEDRON_DEMO_OPERATION_HELPER_H
#include "Scene_item_config.h" //defines SCENE_ITEM_EXPORT
#include <QString>
#include <QStringList>
#include <QMap>
class QAction;
struct QMetaObject;
class QMainWindow;
class QDockWidget;
#include "Polyhedron_demo_plugin_interface.h"
#include "CGAL_demo/Scene_interface.h"
class SCENE_ITEM_EXPORT Polyhedron_demo_plugin_helper
: public Polyhedron_demo_plugin_interface
{
public:
// get action object from its name
static QAction* getActionFromMainWindow(QMainWindow*, QString action_name);
// Init plugin
virtual void init(QMainWindow* mainWindow, Scene_interface* scene_interface);
// Get list of actions supported by this plugin
virtual QStringList actionsNames() const;
virtual QList<QAction*> actions() const;
// To get a selected item with the type of SceneType
template<class SceneType>
SceneType* get_selected_item() const {
int item_id = scene->mainSelectionIndex();
SceneType* scene_item = qobject_cast<SceneType*>(scene->item(item_id));
if(!scene_item) {
// no selected SceneType - if there is only one in list return it, otherwise NULL
int counter = 0;
int last_selected = 0;
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end && counter < 2; ++i) {
if(SceneType* tmp = qobject_cast<SceneType*>(scene->item(i))) {
scene_item = tmp;
counter++;
last_selected=i;
}
}
if(counter != 1) { return NULL; }
scene->setSelectedItem(last_selected);
}
return scene_item;
}
void add_dock_widget(QDockWidget* dock);
// Auto-connect actions to slots. Called by init().
void autoConnectActions();
protected:
QMap<QString, QAction*> actions_map;
Scene_interface* scene;
QMainWindow* mw;
};
#endif // POLYHEDRON_DEMO_OPERATION_HELPER_H

View File

@ -18,8 +18,7 @@
#include <QPointer>
#include <QList>
#include <QAbstractProxyModel>
#include <QMimeData>
GlSplat::SplatRenderer* Scene::ms_splatting = 0;
int Scene::ms_splattingCounter = 0;
@ -30,7 +29,7 @@ GlSplat::SplatRenderer* Scene::splatting()
}
Scene::Scene(QObject* parent)
: QAbstractListModel(parent),
: QStandardItemModel(parent),
selected_item(-1),
item_A(-1),
item_B(-1)
@ -50,6 +49,10 @@ Scene::Scene(QObject* parent)
Scene::Item_id
Scene::addItem(CGAL::Three::Scene_item* item)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item);
if(group)
m_group_entries.prepend(group);
Bbox bbox_before = bbox();
m_entries.push_back(item);
connect(item, SIGNAL(itemChanged()),
@ -63,9 +66,17 @@ Scene::addItem(CGAL::Three::Scene_item* item)
{
Q_EMIT updated_bbox();
}
QAbstractListModel::beginResetModel();
QList<QStandardItem*> list;
for(int i=0; i<5; i++)
{
list<<new QStandardItem();
list.at(i)->setEditable(false);
}
invisibleRootItem()->appendRow(list);
for(int i=0; i<5; i++){
index_map[list.at(i)->index()] = m_entries.size() -1;
}
Q_EMIT updated();
QAbstractListModel::endResetModel();
Item_id id = m_entries.size() - 1;
Q_EMIT newItem(id);
return id;
@ -92,7 +103,7 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
}
Q_EMIT updated();
itemChanged(index);
// QAbstractListModel::reset();
Q_EMIT restoreCollapsedState();
return item;
}
@ -103,50 +114,73 @@ Scene::erase(int index)
return -1;
CGAL::Three::Scene_item* item = m_entries[index];
Q_FOREACH(Scene_group_item* group, m_group_entries)
{
if(group->getChildren().contains(item))
group->removeChild(item);
if (group->getChildren().isEmpty())
{
m_group_entries.removeOne(group);
m_entries.removeOne(group);
}
}
Q_EMIT itemAboutToBeDestroyed(item);
delete item;
m_entries.removeAt(index);
selected_item = -1;
QAbstractListModel::beginResetModel();
QStandardItemModel::beginResetModel();
Q_EMIT updated();
QAbstractListModel::endResetModel();
QStandardItemModel::endResetModel();
if(--index >= 0)
return index;
if(!m_entries.isEmpty())
return 0;
return -1;
}
int
Scene::erase(QList<int> indices)
{
QList<CGAL::Three::Scene_item*> to_be_removed;
clear();
index_map.clear();
int max_index = -1;
Q_FOREACH(int index, indices) {
if(index < 0 || index >= m_entries.size())
continue;
max_index = (std::max)(max_index, index);
CGAL::Three::Scene_item* item = m_entries[index];
to_be_removed.push_back(item);
if(!to_be_removed.contains(item))
to_be_removed.push_back(item);
}
Q_FOREACH(CGAL::Three::Scene_item* item, to_be_removed) {
Q_FOREACH(Scene_item* item, to_be_removed) {
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item);
if(group)
{
m_group_entries.removeAll(group);
}
Q_FOREACH(Scene_group_item* group_item, m_group_entries)
if(group_item->getChildren().contains(item))
group_item->removeChild(item);
Q_EMIT itemAboutToBeDestroyed(item);
delete item;
m_entries.removeAll(item);
}
selected_item = -1;
QAbstractListModel::beginResetModel();
Q_FOREACH(Scene_item* item, m_entries)
{
organize_items(item, invisibleRootItem(), 0);
}
QStandardItemModel::beginResetModel();
Q_EMIT updated();
QAbstractListModel::endResetModel();
QStandardItemModel::endResetModel();
Q_EMIT restoreCollapsedState();
int index = max_index + 1 - indices.size();
if(index >= m_entries.size()) {
index = m_entries.size() - 1;
@ -159,6 +193,16 @@ Scene::erase(QList<int> indices)
}
void Scene::remove_item_from_groups(Scene_item* item)
{
Q_FOREACH(Scene_group_item* group, m_group_entries)
{
if(group->getChildren().contains(item))
{
group->removeChild(item);
}
}
}
Scene::~Scene()
{
Q_FOREACH(CGAL::Three::Scene_item* item_ptr, m_entries)
@ -230,7 +274,7 @@ void Scene::initializeGL()
}
bool
bool
Scene::keyPressEvent(QKeyEvent* e){
bool res=false;
for (QList<int>::iterator it=selected_items_list.begin(),endit=selected_items_list.end();
@ -242,7 +286,7 @@ Scene::keyPressEvent(QKeyEvent* e){
return res;
}
void
void
Scene::draw()
{
draw_aux(false, 0);
@ -252,7 +296,7 @@ Scene::draw(CGAL::Three::Viewer_interface* viewer)
{
draw_aux(false, viewer);
}
void
void
Scene::drawWithNames()
{
draw_aux(true, 0);
@ -283,7 +327,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item)
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
@ -325,7 +369,7 @@ glDepthFunc(GL_LEQUAL);
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item)
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
}
@ -347,7 +391,7 @@ glDepthFunc(GL_LEQUAL);
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item)
if(index == selected_item || selected_items_list.contains(index))
{
item.selection_changed(true);
@ -438,58 +482,41 @@ glDepthFunc(GL_LEQUAL);
// workaround for Qt-4.2 (see above)
#undef lighter
int
Scene::rowCount(const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
else
return m_entries.size();
}
int
Scene::columnCount(const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
else
return NumberOfColumns;
}
QVariant
QVariant
Scene::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if(index.row() < 0 || index.row() >= m_entries.size())
int id = index_map[index];
if(id < 0 || id >= m_entries.size())
return QVariant();
if(role == ::Qt::ToolTipRole)
{
return m_entries[index.row()]->toolTip();
return m_entries[id]->toolTip();
}
switch(index.column())
{
case ColorColumn:
if(role == ::Qt::DisplayRole || role == ::Qt::EditRole)
return m_entries.value(index.row())->color();
return m_entries.value(id)->color();
else if(role == ::Qt::DecorationRole)
return m_entries.value(index.row())->color();
return m_entries.value(id)->color();
break;
case NameColumn:
if(role == ::Qt::DisplayRole || role == ::Qt::EditRole)
return m_entries.value(index.row())->name();
return m_entries.value(id)->name();
if(role == ::Qt::FontRole)
return m_entries.value(index.row())->font();
return m_entries.value(id)->font();
break;
case RenderingModeColumn:
if(role == ::Qt::DisplayRole) {
return m_entries.value(index.row())->renderingModeName();
return m_entries.value(id)->renderingModeName();
}
else if(role == ::Qt::EditRole) {
return static_cast<int>(m_entries.value(index.row())->renderingMode());
return static_cast<int>(m_entries.value(id)->renderingMode());
}
else if(role == ::Qt::TextAlignmentRole) {
return ::Qt::AlignCenter;
@ -497,9 +524,9 @@ Scene::data(const QModelIndex &index, int role) const
break;
case ABColumn:
if(role == ::Qt::DisplayRole) {
if(index.row() == item_A)
if(id == item_A)
return "A";
if(index.row() == item_B)
if(id == item_B)
return "B";
}
else if(role == ::Qt::TextAlignmentRole) {
@ -508,7 +535,7 @@ Scene::data(const QModelIndex &index, int role) const
break;
case VisibleColumn:
if(role == ::Qt::DisplayRole || role == ::Qt::EditRole)
return m_entries.value(index.row())->visible();
return m_entries.value(id)->visible();
break;
default:
return QVariant();
@ -516,7 +543,7 @@ Scene::data(const QModelIndex &index, int role) const
return QVariant();
}
QVariant
QVariant
Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const
{
if(orientation == ::Qt::Horizontal) {
@ -551,32 +578,36 @@ Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const
}
}
}
return QAbstractListModel::headerData(section, orientation, role);
return QStandardItemModel::headerData(section, orientation, role);
}
Qt::ItemFlags
Qt::ItemFlags
Scene::flags ( const QModelIndex & index ) const
{
if (index.isValid() && index.column() == NameColumn) {
return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable;
return QStandardItemModel::flags(index) | ::Qt::ItemIsEditable;
}
else {
return QAbstractListModel::flags(index);
return QStandardItemModel::flags(index);
}
}
bool
Scene::setData(const QModelIndex &index,
bool
Scene::setData(const QModelIndex &index,
const QVariant &value,
int role)
{
if( role != ::Qt::EditRole || !index.isValid() )
return false;
if(index.row() < 0 || index.row() >= m_entries.size())
int id = index_map[index];
if(id < 0 || id >= m_entries.size()){
return false;
}
CGAL::Three::Scene_item* item = m_entries[id];
CGAL::Three::Scene_item* item = m_entries[index.row()];
if(!item) return false;
switch(index.column())
{
@ -601,13 +632,14 @@ Scene::setData(const QModelIndex &index,
rendering_mode = static_cast<RenderingMode>( (rendering_mode+1) % NumberOfRenderingMode );
}
item->setRenderingMode(rendering_mode);
Q_EMIT dataChanged(index, index);
QModelIndex nindex = createIndex(m_entries.size()-1,RenderingModeColumn+1);
Q_EMIT dataChanged(index, nindex);
return true;
break;
}
case VisibleColumn:
item->setVisible(value.toBool());
Q_EMIT dataChanged(index, index);
Q_EMIT dataChanged(index, createIndex(m_entries.size()-1,VisibleColumn+1));
return true;
default:
return false;
@ -615,6 +647,74 @@ Scene::setData(const QModelIndex &index,
return false;
}
bool Scene::dropMimeData(const QMimeData */*data*/,
Qt::DropAction /*action*/,
int /*row*/,
int /*column*/,
const QModelIndex &parent)
{
//gets the moving items
QList<Scene_item*> items;
QList<int> groups_children;
//get IDs of all children of selected groups
Q_FOREACH(int i, selected_items_list)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item(i));
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
groups_children << item_id(child);
}
// Insure that children of selected groups will not be added twice
Q_FOREACH(int i, selected_items_list)
{
if(!groups_children.contains(i))
items << item(i);
}
//Gets the group at the drop position
Scene_group_item* group =
qobject_cast<Scene_group_item*>(this->item(index_map[parent]));
bool one_contained = false;
if(group)
{
Q_FOREACH(int id, selected_items_list)
if(group->getChildren().contains(item(id)))
{
one_contained = true;
break;
}
}
//if the drop item is not a group_item or if it already contains the item, then the drop action must be ignored
if(!group ||one_contained)
{
//unless the drop zone is empty, which means the item should be removed from all groups.
if(!parent.isValid())
{
Q_FOREACH(Scene_item* item, items)
while(item->has_group!=0)
{
Q_FOREACH(Scene_group_item* group_item, m_group_entries)
if(group_item->getChildren().contains(item))
{
group_item->removeChild(item);
break;
}
}
group_added();
return true;
}
return false;
}
Q_FOREACH(Scene_item* item, items)
changeGroup(item, group);
//group->addChild(item(mainSelectionIndex()));
group_added();
return true;
}
Scene::Item_id Scene::mainSelectionIndex() const {
return selected_item;
}
@ -633,14 +733,14 @@ int Scene::selectionBindex() const {
QItemSelection Scene::createSelection(int i)
{
return QItemSelection(this->createIndex(i, 0),
this->createIndex(i, LastColumn));
return QItemSelection(index_map.keys(i).at(0),
index_map.keys(i).at(4));
}
QItemSelection Scene::createSelectionAll()
{
return QItemSelection(this->createIndex(0, 0),
this->createIndex(m_entries.size() - 1 , LastColumn));
return QItemSelection(index_map.keys(0).at(0),
index_map.keys(m_entries.size() - 1).at(4));
}
void Scene::itemChanged()
@ -657,6 +757,7 @@ void Scene::itemChanged(Item_id i)
Q_EMIT dataChanged(this->createIndex(i, 0),
this->createIndex(i, LastColumn));
// Q_EMIT restoreCollapsedState();
}
void Scene::itemChanged(CGAL::Three::Scene_item* /* item */)
@ -673,6 +774,7 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
Q_ASSERT(proxyModel);
Scene *scene = dynamic_cast<Scene*>(proxyModel->sourceModel());
Q_ASSERT(scene);
int id = scene->index_map[proxyModel->mapToSource(index)];
switch(index.column()) {
case Scene::VisibleColumn:
if (event->type() == QEvent::MouseButtonPress) {
@ -681,7 +783,7 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
int x = mouseEvent->pos().x() - option.rect.x();
if(x >= (option.rect.width() - size)/2 &&
x <= (option.rect.width() + size)/2) {
model->setData(index, ! model->data(index).toBool() );
model->setData(index, !model->data(index).toBool());
}
}
return false; //so that the selection can change
@ -724,19 +826,19 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
break;
case Scene::ABColumn:
if (event->type() == QEvent::MouseButtonPress) {
if(index.row() == scene->item_B) {
scene->item_A = index.row();
if(id == scene->item_B) {
scene->item_A = id;
scene->item_B = -1;
}
else if(index.row() == scene->item_A) {
scene->item_B = index.row();
else if(id == scene->item_A) {
scene->item_B = id;
scene->item_A = -1;
}
else if(scene->item_A == -1) {
scene->item_A = index.row();
scene->item_A = id;
}
else {
scene->item_B = index.row();
scene->item_B = id;
}
scene->dataChanged(scene->createIndex(0, Scene::ABColumn),
scene->createIndex(scene->rowCount() - 1, Scene::ABColumn));
@ -751,31 +853,35 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QModelIndex test = proxy->mapToSource(index);
if (index.column() != Scene::VisibleColumn) {
QItemDelegate::paint(painter, option, index);
} else {
const QAbstractItemModel *model = index.model();
QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ?
(option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled;
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight));
bool checked = model->data(index, ::Qt::DisplayRole).toBool();
int width = option.rect.width();
int height = option.rect.height();
size = (std::min)(width, height);
int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);;
int y = option.rect.y() + (option.rect.height() / 2) - (size / 2);
if(checked) {
painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size),
::Qt::KeepAspectRatio,
::Qt::SmoothTransformation));
}
else {
painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size),
::Qt::KeepAspectRatio,
::Qt::SmoothTransformation));
if(test.row()>=0 && test.row()<scene->m_entries.size()){
if(checked) {
painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size),
::Qt::KeepAspectRatio,
::Qt::SmoothTransformation));
}
else {
painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size),
::Qt::KeepAspectRatio,
::Qt::SmoothTransformation));
}
}
drawFocus(painter, option, option.rect); // since we draw the grid ourselves
}
@ -850,6 +956,44 @@ Scene::Bbox Scene::bbox() const
}
return bbox;
}
QList<Scene_group_item*> Scene::group_entries() const
{
return m_group_entries;
}
QList<Scene_item*> Scene::item_entries() const
{
return m_entries;
}
void Scene::group_added()
{
//makes the hierarchy in the tree
//clears the model
clear();
index_map.clear();
//fills the model
Q_FOREACH(Scene_item* item, m_entries)
{
organize_items(item, invisibleRootItem(), 0);
}
Q_EMIT restoreCollapsedState();
}
void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group)
{
//remove item from the containing group if any
if(item->has_group!=0)
Q_FOREACH(Scene_group_item* group, m_group_entries)
{
if(group->getChildren().contains(item))
{
remove_item_from_groups(item);
break;
}
}
//add the item to the target group
target_group->addChild(item);
item->has_group = target_group->has_group +1;
}
float Scene::get_bbox_length() const
{
@ -859,6 +1003,60 @@ float Scene::get_bbox_length() const
#include "Scene_find_items.h"
void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop)
{
if(item->has_group <= loop)
{
QList<QStandardItem*> list;
for(int i=0; i<5; i++)
{
list<<new QStandardItem();
list.at(i)->setEditable(false);
}
root->appendRow(list);
for(int i=0; i<5; i++){
index_map[list.at(i)->index()] = m_entries.indexOf(item);
}
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item);
if(group)
{
Q_FOREACH(Scene_item*child, group->getChildren())
{
organize_items(child, list.first(), loop+1);
}
}
}
}
void Scene::setExpanded(QModelIndex id)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item(index_map.value(index(0, 0, id.parent()))));
if(group)
{
group->setExpanded(true);
}
}
void Scene::setCollapsed(QModelIndex id)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item(index_map.value(index(0, 0, id.parent()))));
if(group)
group->setExpanded(false);
}
int Scene::getIdFromModelIndex(QModelIndex modelId)const
{
return index_map.value(modelId);
}
QList<QModelIndex> Scene::getModelIndexFromId(int id) const
{
return index_map.keys(id);
}
namespace scene { namespace details {
Q_DECL_EXPORT
@ -878,6 +1076,7 @@ findItem(const CGAL::Three::Scene_interface* scene_interface,
Q_DECL_EXPORT
QList<CGAL::Three::Scene_item*>
findItems(const CGAL::Three::Scene_interface* scene_interface,
const QMetaObject&,
QString name, Scene_item_name_fn_ptr fn)
{

View File

@ -3,25 +3,25 @@
#define SCENE_H
#include "config.h"
#include "Scene_config.h"
#include <CGAL/Three/Scene_interface.h>
#include <CGAL/Three/Scene_draw_interface.h>
#include <CGAL/Three/Viewer_config.h>
#include <QtOpenGL/qgl.h>
#include <QAbstractListModel>
#include <QStandardItemModel>
#include <QString>
#include <QColor>
#include <QList>
#include <QMap>
#include <QItemDelegate>
#include <QPixmap>
#include <QItemSelection>
#include <QGLViewer/qglviewer.h>
#include <QDebug>
#include <iostream>
#include <cmath>
#include <boost/variant.hpp>
#include "Scene_group_item.h"
class QEvent;
class QMouseEvent;
namespace GlSplat { class SplatRenderer; }
@ -29,7 +29,8 @@ namespace CGAL { namespace Three{ class Viewer_interface;}}
class SCENE_EXPORT Scene :
public QAbstractListModel, public CGAL::Three::Scene_interface, public CGAL::Three::Scene_draw_interface
public QStandardItemModel, public CGAL::Three::Scene_interface, public CGAL::Three::Scene_draw_interface
{
Q_OBJECT
Q_PROPERTY(int numberOfEntries READ numberOfEntries)
@ -37,6 +38,8 @@ class SCENE_EXPORT Scene :
friend class SceneDelegate;
public:
QList<QModelIndex> getModelIndexFromId(int id) const;
int getIdFromModelIndex(QModelIndex modelId) const;
enum Columns { NameColumn = 0,
ColorColumn,
RenderingModeColumn,
@ -50,8 +53,11 @@ public:
//!Adds item to the items list, gives it an ID and
//!updates the bounding box if needed.
int addItem(CGAL::Three::Scene_item* item);
//!Sets item as the item at index and calls @ref Scene_item#changed().
//!Moves item to the targeted group.
void changeGroup(CGAL::Three::Scene_item* item, Scene_group_item* target_group);
//!Sets item as the item at index and calls @ref Scene_item#changed().
//!If emit_item_about_to_be_destroyed is set to true, emits
//!an itemAboutToBeDestroyed signal.
CGAL::Three::Scene_item* replaceItem(int index, CGAL::Three::Scene_item* item, bool emit_item_about_to_be_destroyed = false);
@ -134,12 +140,9 @@ public:
return std::sqrt(dx*dx + dy*dy + dz*dz);
}
// QAbstractItemModel functions
//!@returns the number of items, which is also the sumber of rows in the sceneView.
int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
//!@returns the number of columns in the sceneView.
int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
//!@returns the column data corresponding to role.
// QStandardItemModel functions
bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &parent);
QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const;
//!@returns the type of data correspondind to the role.
QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const;
@ -148,7 +151,8 @@ public:
/*! Sets the column data for the target index. Returns false if index is not valid and
* if role is not EditRole.*/
bool setData(const QModelIndex &index, const QVariant &value, int role);
QList<Scene_group_item*> group_entries() const ;
QList<CGAL::Three::Scene_item*> item_entries() const ;
// auxiliary public function for QMainWindow
//!Selects the row at index i in the sceneView.
QItemSelection createSelection(int i);
@ -169,6 +173,10 @@ public Q_SLOTS:
* Calls @ref Scene_item#changed().
* This function is called by the items.*/
void itemChanged(CGAL::Three::Scene_item*);
//!Removes item from all the groups of the scene.
void remove_item_from_groups(CGAL::Three::Scene_item* item);
//!Re-organizes the sceneView.
void group_added();
//! Sets the selected item to the target index.
void setSelectedItemIndex(int i)
{
@ -179,7 +187,8 @@ public Q_SLOTS:
{
selected_item = i;
Q_EMIT selectionChanged(i);
};
}
//! Sets the target item as selected and emits setSelectedItem for its index.
void setSelectedItem(CGAL::Three::Scene_item* item_to_select)
{
@ -193,12 +202,26 @@ public Q_SLOTS:
}
++i;
}
};
}
//! Sets the target list of indices as the selected indices.
void setSelectedItemsList(QList<int> l )
QList<int> setSelectedItemsList(QList<int> l )
{
Q_FOREACH(int i,l)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item(i));
if(group)
{
QList<int> list;
Q_FOREACH(CGAL::Three::Scene_item* child, group->getChildren())
list<<m_entries.indexOf(child);
l << setSelectedItemsList(list);
}
}
selected_items_list = l;
};
return l;
}
// Accessors (setters)
//!Sets the item at index i to visible or not visible.
@ -216,8 +239,12 @@ Q_SIGNALS:
void itemAboutToBeDestroyed(CGAL::Three::Scene_item*);
void selectionRay(double, double, double, double, double, double);
void selectionChanged(int i);
void restoreCollapsedState();
private Q_SLOTS:
//!Specifies a group as Expanded for the view
void setExpanded(QModelIndex);
//!Specifies a group as Collapsed for the view
void setCollapsed(QModelIndex);
//! Casts a selection ray and calls the item function select.
void setSelectionRay(double, double, double, double, double, double);
void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();}
@ -227,12 +254,16 @@ private:
* to its current renderingMode. If with_names is true, uses
* the OpenGL mode GL_WITH_NAMES, essentially used for the picking.*/
void draw_aux(bool with_names, CGAL::Three::Viewer_interface*);
//! Re-draw the hierarchy of the view.
void organize_items(CGAL::Three::Scene_item* item, QStandardItem *root, int loop);
//! List of Scene_items.
typedef QList<CGAL::Three::Scene_item*> Entries;
//!List containing all the scene_items.
Entries m_entries;
//! Index of the currently selected item.
int selected_item;
//!List containing all the scene_group_items.
QList<Scene_group_item*> m_group_entries;
//!List of indices of the currently selected items.
QList<int> selected_items_list;
//!Index of the item_A.
@ -241,10 +272,14 @@ private:
int item_B;
static GlSplat::SplatRenderer* ms_splatting;
static int ms_splattingCounter;
QMap<QModelIndex, int> index_map;
public:
static GlSplat::SplatRenderer* splatting();
}; // end class Scene
class QAbstractProxyModel;
/*!
* \brief The SceneDelegate class
* Handles the columns of the sceneView
@ -265,11 +300,21 @@ public:
//! Draws the content of the sceneView
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void setProxy(QAbstractProxyModel* p_proxy){
proxy = p_proxy;
}
void setScene(Scene* p_scene){
scene = p_scene;
}
private:
QPixmap checkOnPixmap;
QPixmap checkOffPixmap;
QAbstractProxyModel *proxy;
Scene *scene;
mutable int size;
}; // end class SceneDelegate
#endif // SCENE_H

View File

@ -16,19 +16,19 @@ typedef QString (CGAL::Three::Scene_item ::*Scene_item_name_fn_ptr)() const;
// Declaration only (defined in Scene.cpp)
SCENE_EXPORT
CGAL::Three::Scene_item*
findItem(const Scene_interface* scene_interface,
findItem(const CGAL::Three::Scene_interface* scene_interface,
const QMetaObject& metaobj,
QString name, Scene_item_name_fn_ptr fn);
// Declaration only (defined in Scene.cpp)
SCENE_EXPORT
QList<CGAL::Three::Scene_item*>
findItems(const Scene_interface* scene_interface,
findItems(const CGAL::Three::Scene_interface* scene_interface,
const QMetaObject& metaobj,
QString name, Scene_item_name_fn_ptr fn); // fwd declaration
template <typename T>
T findItem(const Scene_interface* scene, QString name,
T findItem(const CGAL::Three::Scene_interface* scene, QString name,
Scene_item_name_fn_ptr fn)
{
return
@ -38,7 +38,7 @@ T findItem(const Scene_interface* scene, QString name,
}
template <typename T>
QList<T> findItems(const Scene_interface* scene, QString name,
QList<T> findItems(const CGAL::Three::Scene_interface* scene, QString name,
Scene_item_name_fn_ptr fn)
{
QList<CGAL::Three::Scene_item*> void_list =
@ -60,7 +60,7 @@ QList<T> findItems(const Scene_interface* scene, QString name,
accepted.
*/
template <typename T>
T findItem(const Scene_interface* scene,
T findItem(const CGAL::Three::Scene_interface* scene,
QString item_name = QString())
{ return details::findItem<T>(scene, item_name, &CGAL::Three::Scene_item::name); }
@ -69,7 +69,7 @@ T findItem(const Scene_interface* scene,
accepted.
*/
template <typename T>
QList<T> findItems(const Scene_interface* scene,
QList<T> findItems(const CGAL::Three::Scene_interface* scene,
QString item_name = QString())
{ return details::findItems<T>(scene, item_name, &CGAL::Three::Scene_item::name); }
@ -78,7 +78,7 @@ QList<T> findItems(const Scene_interface* scene,
omitted, all names are accepted.
*/
template <typename T>
T findItemByObjectName(const Scene_interface* scene,
T findItemByObjectName(const CGAL::Three::Scene_interface* scene,
QString obj_name = QString())
{ return details::findItem<T>(scene, obj_name, &QObject::objectName); }
@ -87,7 +87,7 @@ T findItemByObjectName(const Scene_interface* scene,
names are accepted.
*/
template <typename T>
QList<T> findItemsByObjectName(const Scene_interface* scene,
QList<T> findItemsByObjectName(const CGAL::Three::Scene_interface* scene,
QString obj_name = QString())
{ return details::findItems<T>(scene, obj_name, &QObject::objectName); }

View File

@ -0,0 +1,113 @@
#include "Scene_group_item.h"
#include <QDebug>
Scene_group_item::Scene_group_item(QString name)
: Scene_item(0,0)
{
this->name_ = name;
expanded = true;
}
bool Scene_group_item::isFinite() const
{
Q_FOREACH(Scene_item *item, children)
if(!item->isFinite()){
return false;
}
return true;
}
bool Scene_group_item::isEmpty() const {
Q_FOREACH(Scene_item *item, children)
if(!item->isEmpty()){
return true;
}
return true;
}
Scene_group_item::Bbox Scene_group_item::bbox() const
{
return Bbox(0, 0, 0, 0, 0,0);
}
bool Scene_group_item::supportsRenderingMode(RenderingMode m) const {
Q_FOREACH(Scene_item* item, children)
if(!item->supportsRenderingMode(m))
return false;
return !children.isEmpty();
}
QString Scene_group_item::toolTip() const {
QString str =
QObject::tr( "<p>Number of children: %1<br />").arg(children.size());
str+="</p>";
str += QString("Bounding box: min (%1,%2,%3), max(%4,%5,%6)")
.arg(bbox().xmin)
.arg(bbox().ymin)
.arg(bbox().zmin)
.arg(bbox().xmax)
.arg(bbox().ymax)
.arg(bbox().zmax);
return str;
}
void Scene_group_item::addChild(Scene_item* new_item)
{
if(!children.contains(new_item))
{
children.append(new_item);
add_group_number(new_item);
}
}
void Scene_group_item::add_group_number(Scene_item * new_item)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(new_item);
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
add_group_number(child);
new_item->has_group++;
}
void Scene_group_item::setColor(QColor c)
{
Scene_item::setColor(c);
Q_FOREACH(Scene_item* child, children)
{
child->setColor(c);
}
}
void Scene_group_item::setRenderingMode(RenderingMode m)
{
Scene_item::setRenderingMode(m);
Q_FOREACH(Scene_item* child, children)
{
child->setRenderingMode(m);
}
}
void Scene_group_item::setVisible(bool b)
{
Scene_item::setVisible(b);
Q_FOREACH(Scene_item* child, children)
{
child->setVisible(b);
}
}
bool Scene_group_item::isExpanded() const
{
return expanded;
}
void Scene_group_item::setExpanded(bool b)
{
expanded = b;
}

View File

@ -0,0 +1,95 @@
#ifndef SCENE_GROUP_ITEM_H
#define SCENE_GROUP_ITEM_H
#include <CGAL/Three/Scene_item.h>
#include "Messages_interface.h"
using namespace CGAL::Three;
class Q_DECL_EXPORT Scene_group_item : public Scene_item
{
Q_OBJECT
public :
Scene_group_item(QString name = QString());
~Scene_group_item() {}
bool isFinite() const;
bool isEmpty() const ;
bool isExpanded() const;
void setExpanded(bool);
Bbox bbox() const;
Scene_group_item* clone() const {return 0;}
//! Indicate if rendering mode is supported.
bool supportsRenderingMode(RenderingMode m) const;
QString toolTip() const;
void addChild(Scene_item* new_item);
void setColor(QColor c);
void setRenderingMode(RenderingMode m);
void setVisible(bool b);
void setPointsMode() {
setRenderingMode(Points);
}
void setWireframeMode() {
setRenderingMode(Wireframe);
}
void setWireframe() {
setRenderingMode(Wireframe);
}
void setFlat() {
setRenderingMode(Flat);
}
void setFlatMode() {
setRenderingMode(Flat);
}
void setFlatPlusEdgesMode() {
setRenderingMode(FlatPlusEdges);
}
void setGouraudMode() {
setRenderingMode(Gouraud);
}
void setPointsPlusNormalsMode(){
setRenderingMode(PointsPlusNormals);
}
void setSplattingMode(){
setRenderingMode(Splatting);
}
QList<Scene_item*> getChildren() const {return children;}
void removeChild( Scene_item* item)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item);
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
removeChild(child);
item->has_group=0;
children.removeOne(item);
}
Q_SIGNALS:
void updated(int row, int column);
private:
QList<Scene_item*> children;
void add_group_number(Scene_item*new_item);
bool expanded;
}; //end of class Scene_group_item
#endif // SCENE_GROUP_ITEM_H

View File

@ -845,7 +845,6 @@ void Scene_polyhedron_item::draw(CGAL::Three::Viewer_interface* viewer) const {
initialize_buffers(viewer);
}
if(renderingMode() == Flat || renderingMode() == FlatPlusEdges)
vaos[Facets]->bind();
else

View File

@ -96,6 +96,7 @@ public:
buffers[i].create();
}
nb_isolated_vertices = 0;
has_group = 0;
}
//!The Constructor.
/*!
@ -127,6 +128,7 @@ public:
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;}
@ -222,6 +224,7 @@ public:
//!Handles key press events.
virtual bool keyPressEvent(QKeyEvent*){return false;}
int has_group;
public Q_SLOTS:
//! Notifies the program that the internal data or the properties of