Dialogbox for import fully functionnal

This commit is contained in:
atlante45 2013-08-19 15:54:51 -07:00
parent b4157593c5
commit 24531fdd10
12 changed files with 275 additions and 86 deletions

View file

@ -1199,13 +1199,13 @@ void Application::importVoxelsToClipboard() {
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
const char* fileName = fileNameAscii.data();
_clipboardTree.eraseAllVoxels();
_clipboard.killLocalVoxels();
if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) {
_clipboardTree.readFromSquareARGB32Pixels(fileName);
_clipboard.readFromSquareARGB32Pixels(fileName);
} else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) {
_clipboardTree.readFromSVOFile(fileName);
_clipboard.readFromSVOFile(fileName);
} else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) {
_clipboardTree.readFromSchematicFile(fileName);
_clipboard.readFromSchematicFile(fileName);
}
// restore the main window's active state
@ -1213,6 +1213,16 @@ void Application::importVoxelsToClipboard() {
}
void Application::importVoxels() {
if (_voxelImporter.exec()) {
qDebug("[DEBUG] Import succedded.\n");
} else {
qDebug("[DEBUG] Import failed.\n");
}
return;
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QStringList fileNameStringList = QFileDialog::getOpenFileNames(_glWidget, tr("Import Voxels"), desktopLocation,
@ -1369,10 +1379,10 @@ void Application::copyVoxels() {
VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
if (selectedNode) {
// clear the clipboard first...
_clipboardTree.eraseAllVoxels();
_clipboard.killLocalVoxels();
// then copy onto it
_voxels.copySubTreeIntoNewTree(selectedNode, &_clipboardTree, true);
//_voxels.copySubTreeIntoNewTree(selectedNode, _clipboard, true);
}
}
@ -1393,7 +1403,7 @@ void Application::pasteVoxels() {
args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
}
_clipboardTree.recurseTreeWithOperation(sendVoxelsOperation, &args);
//_clipboard.recurseTreeWithOperation(sendVoxelsOperation, &args);
_voxelEditSender.flushQueue();
if (calculatedOctCode) {

View file

@ -239,7 +239,7 @@ private:
Stars _stars;
VoxelSystem _voxels;
VoxelTree _clipboardTree; // if I copy/paste
VoxelSystem _clipboard; // if I copy/paste
VoxelImporter _voxelImporter;
QByteArray _voxelsFilename;

View file

@ -9,8 +9,10 @@
#include <QStandardPaths>
#include <QGridLayout>
#include <QMouseEvent>
const QString WINDOW_NAME = QObject::tr("Import Voxels");
const QString IMPORT_BUTTON_NAME = QObject::tr("Import");
const QString IMPORT_TO_CLIPBOARD_CHECKBOX_STRING = QObject::tr("Import into clipboard");
const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview");
const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, "
@ -20,8 +22,14 @@ const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Oc
const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
const glm::vec3 UP = glm::vec3(0, 1, 0);
const float ANGULAR_RATE = 0.02f;
const float VERTICAL_ANGLE = M_PI_4 / 2.0f;
const float RETURN_RATE = 0.02f;
const float NEAR_CLIP = 0.5f;
const float FAR_CLIP = 10.0f;
const float FIELD_OF_VIEW = 60.0f;
class GLWidget : public QGLWidget {
public:
@ -31,17 +39,25 @@ public:
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void resizeGL(int width, int height);
virtual void paintGL();
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
VoxelSystem* _voxelSystem;
bool _draw;
float _a;
float _h;
double _a; // horizontal angle of the camera to the center of the object
double _h; // vertical angle of the camera to the center of the object
glm::vec3 _targetCenter;
bool _pressed;
int _mouseX;
int _mouseY;
};
GLWidget::GLWidget(QWidget *parent, VoxelSystem *voxelSystem)
@ -49,8 +65,11 @@ GLWidget::GLWidget(QWidget *parent, VoxelSystem *voxelSystem)
_voxelSystem(voxelSystem),
_draw(false),
_a(0.0f),
_h(0.0f),
_targetCenter(0.5f, 0.5f, 0.5f) {
_h(VERTICAL_ANGLE),
_targetCenter(0.5f, 0.5f, 0.5f),
_pressed(false),
_mouseX(0),
_mouseY(0) {
}
void GLWidget::initializeGL() {
@ -65,12 +84,15 @@ void GLWidget::initializeGL() {
}
void GLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
void GLWidget::resizeGL(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (float) w / h, 0.25f, 500);
gluPerspective(FIELD_OF_VIEW,
(float) width / height,
NEAR_CLIP,
FAR_CLIP);
}
void GLWidget::paintGL() {
@ -80,10 +102,14 @@ void GLWidget::paintGL() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
_a += ANGULAR_RATE;
gluLookAt(_targetCenter.x + (glm::length(_targetCenter) + 0.5f) * cos((double) _a),
_targetCenter.y * 1.25f,
_targetCenter.z + (glm::length(_targetCenter) + 0.5f) * sin((double) _a),
if (!_pressed) {
_a += ANGULAR_RATE;
_h = (1.0f - RETURN_RATE) * _h + RETURN_RATE * VERTICAL_ANGLE;
}
gluLookAt(_targetCenter.x + (glm::length(_targetCenter) + NEAR_CLIP) * cos(_a),
_targetCenter.y + (glm::length(_targetCenter) + NEAR_CLIP) * sin(_h),
_targetCenter.z + (glm::length(_targetCenter) + NEAR_CLIP) * sin(_a),
_targetCenter.x, _targetCenter.y, _targetCenter.z,
UP.x, UP.y, UP.z);
@ -102,7 +128,7 @@ void GLWidget::paintGL() {
glColor3d(0.4f, 0.4f ,0.4f);
glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y,2 * _targetCenter.z);
glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z);
glVertex3d(0 , 2 * _targetCenter.y, 2 * _targetCenter.z);
glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z);
@ -116,18 +142,40 @@ void GLWidget::paintGL() {
}
}
void GLWidget::mousePressEvent(QMouseEvent* event) {
_pressed = true;
_mouseX = event->globalX();
_mouseY = event->globalY();
}
void GLWidget::mouseMoveEvent(QMouseEvent* event) {
_a += (M_PI * (event->globalX() - _mouseX)) / height();
_h += (M_PI * (event->globalY() - _mouseY)) / height();
_h = glm::clamp(_h, -M_PI_4, M_PI_4);
_mouseX = event->globalX();
_mouseY = event->globalY();
}
void GLWidget::mouseReleaseEvent(QMouseEvent* event) {
_pressed = false;
}
ImportDialog::ImportDialog(QWidget *parent, VoxelSystem* voxelSystem)
: QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES),
_clipboardImportBox (IMPORT_TO_CLIPBOARD_CHECKBOX_STRING, this),
_previewBox (PREVIEW_CHECKBOX_STRING, this),
_previewBar (this),
_glPreview (new GLWidget(this, voxelSystem)) {
_importButton (IMPORT_BUTTON_NAME, this),
_clipboardImportBox(IMPORT_TO_CLIPBOARD_CHECKBOX_STRING, this),
_previewBox (PREVIEW_CHECKBOX_STRING, this),
_previewBar (this),
_glPreview (new GLWidget(this, voxelSystem)) {
setOption(QFileDialog::DontUseNativeDialog, true);
setFileMode(QFileDialog::ExistingFile);
setViewMode(QFileDialog::Detail);
QGridLayout* gridLayout = (QGridLayout*) layout();
gridLayout->addWidget(&_importButton , 2, 2);
gridLayout->addWidget(&_clipboardImportBox, 2, 3);
gridLayout->addWidget(&_previewBox , 3, 3);
gridLayout->addWidget(&_previewBar , 0, 3);
@ -138,43 +186,71 @@ ImportDialog::ImportDialog(QWidget *parent, VoxelSystem* voxelSystem)
_previewBar.setRange(0, 100);
_previewBar.setValue(0);
connect(&_importButton, SIGNAL(pressed()), SLOT(import()));
connect(&_previewBox, SIGNAL(toggled(bool)), SIGNAL(previewToggled(bool)));
connect(&_previewBox, SIGNAL(toggled(bool)), SLOT(preview(bool)));
connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString)));
connect(&_glTimer, SIGNAL(timeout()), SLOT(timer()));
connect(voxelSystem->getVoxelTree(), SIGNAL(importSize(float,float,float)), SLOT(setGLCamera(float, float, float)));
connect(voxelSystem->getVoxelTree(), SIGNAL(importProgress(int)), &_previewBar, SLOT(setValue(int)));
connect(voxelSystem, SIGNAL(importSize(float,float,float)), SLOT(setGLCamera(float, float, float)));
connect(voxelSystem, SIGNAL(importProgress(int)), &_previewBar, SLOT(setValue(int)));
}
ImportDialog::~ImportDialog() {
delete _glPreview;
}
void ImportDialog::import() {
_importButton.setDisabled(true);
_clipboardImportBox.setDisabled(true);
_previewBox.setDisabled(true);
_previewBar.setValue(0);
_previewBar.setVisible(true);
emit accepted();
}
void ImportDialog::accept() {
QFileDialog::accept();
}
void ImportDialog::reject() {
QFileDialog::reject();
}
int ImportDialog::exec() {
_previewBox.setChecked(false);
_previewBar.setVisible(false);
reset();
int ret = QFileDialog::exec();
((GLWidget*) _glPreview)->setDraw(false);
_glTimer.stop();
_glPreview->updateGL();
preview(false);
return ret;
}
void ImportDialog::setGLCamera(float x, float y, float z) {
((GLWidget*) _glPreview)->setTargetCenter(glm::vec3(x, y, z) / 2.0f);
_glPreview->setTargetCenter(glm::vec3(x, y, z) / 2.0f);
}
void ImportDialog::reset() {
_previewBox.setChecked(false);
_previewBar.setVisible(false);
_previewBar.setValue(0);
_importButton.setEnabled(true);
_clipboardImportBox.setEnabled(true);
_previewBox.setEnabled(true);
_glTimer.stop();
_glPreview->setDraw(false);
_glPreview->updateGL();
}
void ImportDialog::preview(bool wantPreview) {
_previewBar.setValue(0);
_previewBar.setVisible(wantPreview);
((GLWidget*) _glPreview)->setDraw(wantPreview);
_glPreview->setDraw(wantPreview);
if (wantPreview) {
emit previewActivated(_currentFile);
_glTimer.start();
} else {
_glTimer.stop();

View file

@ -18,20 +18,30 @@
#include <QGLWidget>
#include <QTimer>
class GLWidget;
class ImportDialog : public QFileDialog {
Q_OBJECT
public:
ImportDialog(QWidget* parent = NULL, VoxelSystem* voxelSystem = NULL);
~ImportDialog();
bool getWantPreview() const { return _previewBox.isChecked(); }
QString getCurrentFile() const { return _currentFile; }
bool getImportIntoClipboard() const { return _clipboardImportBox.isChecked(); }
void reset();
signals:
void previewActivated(QString);
void previewToggled(bool);
void accepted();
public slots:
int exec();
void setGLCamera(float x, float y, float z);
void import();
void accept();
void reject();
private slots:
void preview(bool preview);
@ -40,10 +50,11 @@ private slots:
private:
QString _currentFile;
QPushButton _importButton;
QCheckBox _clipboardImportBox;
QCheckBox _previewBox;
QProgressBar _previewBar;
QGLWidget* _glPreview;
GLWidget* _glPreview;
QTimer _glTimer;
};

View file

@ -233,11 +233,6 @@ Menu::Menu() :
addActionToQMenuAndActionHash(voxelMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
addActionToQMenuAndActionHash(voxelMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels()));
addActionToQMenuAndActionHash(voxelMenu,
MenuOption::ImportVoxelsClipboard,
Qt::SHIFT | Qt::CTRL | Qt::Key_I,
appInstance,
SLOT(importVoxelsToClipboard()));
addActionToQMenuAndActionHash(voxelMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels()));
addActionToQMenuAndActionHash(voxelMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels()));
addActionToQMenuAndActionHash(voxelMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels()));
@ -776,4 +771,4 @@ void Menu::updateFrustumRenderModeAction() {
frustumRenderModeAction->setText("Render Mode - Keyhole");
break;
}
}
}

View file

@ -11,11 +11,21 @@
#include <QFileInfo>
#include <QThreadPool>
class ImportTask : public QObject, public QRunnable {
public:
ImportTask(VoxelSystem* voxelSystem, const QString &filename);
void run();
private:
VoxelSystem* _voxelSystem;
QString _filename;
};
class LocalVoxelSystem : public VoxelSystem {
public:
LocalVoxelSystem() : VoxelSystem(1) {};
LocalVoxelSystem() : VoxelSystem(1, 2000000) {}
virtual void removeOutOfView() {};
virtual void removeOutOfView() {}
};
VoxelImporter::VoxelImporter(QWidget* parent)
@ -25,38 +35,107 @@ VoxelImporter::VoxelImporter(QWidget* parent)
_currentTask(NULL),
_nextTask(NULL) {
connect(&_importDialog, SIGNAL(previewActivated(QString)), SLOT(preImport(QString)));
connect(&_importDialog, SIGNAL(currentChanged(QString)) , SLOT(preImport(QString)));
connect(&_importDialog, SIGNAL(previewToggled(bool)), SLOT(preImport()));
connect(&_importDialog, SIGNAL(currentChanged(QString)), SLOT(preImport()));
connect(&_importDialog, SIGNAL(accepted()), SLOT(import()));
}
void VoxelImporter::import(const QString &filename) {
_importDialog.reset();
_filename = filename;
_currentTask = NULL;
_nextTask = NULL;
if (_filename == "") {
_importDialog.exec();
VoxelImporter::~VoxelImporter() {
if (_nextTask) {
delete _nextTask;
_nextTask = NULL;
}
if (_currentTask) {
disconnect(_currentTask, 0, 0, 0);
connect(_currentTask, SIGNAL(destroyed()), _voxelSystem, SLOT(deleteLater()));
_voxelSystem->cancelImport();
_currentTask = NULL;
} else {
delete _voxelSystem;
}
}
void VoxelImporter::preImport(const QString &filename) {
if (_importDialog.getWantPreview() && QFileInfo(filename).isFile()) {
void VoxelImporter::reset() {
_voxelSystem->killLocalVoxels();
_importDialog.reset();
_filename = "";
_currentTask = NULL;
_nextTask = NULL;
}
int VoxelImporter::exec() {
reset();
int ret = _importDialog.exec();
if (!ret) {
if (_nextTask) {
delete _nextTask;
_nextTask = NULL;
}
if (_currentTask) {
_voxelSystem->cancelImport();
}
}
return ret;
}
int VoxelImporter::preImport() {
QString filename = _importDialog.getCurrentFile();
if (!QFileInfo(filename).isFile()) {
return 0;
}
if (_importDialog.getWantPreview()) {
_filename = filename;
_nextTask = new ImportTask(_voxelSystem, _filename);
connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask()));
_importDialog.reset();
if (_currentTask != NULL) {
_voxelSystem->getVoxelTree()->cancelImport();
_voxelSystem->cancelImport();
} else {
launchTask();
}
}
return 1;
}
int VoxelImporter::import() {
QString filename = _importDialog.getCurrentFile();
if (!QFileInfo(filename).isFile()) {
_importDialog.reject();
return 0;
}
if (_filename == filename) {
if (_currentTask) {
connect(_currentTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept()));
} else {
_importDialog.accept();
}
return 1;
}
_filename = filename;
_nextTask = new ImportTask(_voxelSystem, _filename);
connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask()));
connect(_nextTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept()));
if (_currentTask != NULL) {
_voxelSystem->cancelImport();
} else {
launchTask();
}
return 1;
}
void VoxelImporter::launchTask() {
@ -73,7 +152,6 @@ void VoxelImporter::launchTask() {
ImportTask::ImportTask(VoxelSystem* voxelSystem, const QString &filename)
: _voxelSystem(voxelSystem),
_filename(filename) {
}
void ImportTask::run() {
@ -82,8 +160,7 @@ void ImportTask::run() {
} else if (_filename.endsWith(".svo", Qt::CaseInsensitive)) {
_voxelSystem->readFromSVOFile(_filename.toLocal8Bit().data());
} else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) {
qDebug("[DEBUG] %d.\n",
_voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data()));
_voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data());
} else {
qDebug("[ERROR] Invalid file extension.\n");
}

View file

@ -15,33 +15,30 @@
#include <QThread>
#include <QRunnable>
class ImportTask : public QObject, public QRunnable {
Q_OBJECT
public:
ImportTask(VoxelSystem* voxelSystem, const QString &filename);
void run();
private:
VoxelSystem* _voxelSystem;
QString _filename;
};
class ImportTask;
class LocalVoxelSystem;
class VoxelImporter : public QObject {
Q_OBJECT
public:
VoxelImporter(QWidget* parent = NULL);
~VoxelImporter();
void reset();
void init();
VoxelSystem* getVoxelSystem() const { return _voxelSystem; }
bool getimportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); }
public slots:
void import(const QString &filename = "");
void preImport(const QString &filename);
int exec();
int preImport();
int import();
private slots:
void launchTask();
private:
VoxelSystem* _voxelSystem;
ImportDialog _importDialog;
QString _filename;

View file

@ -65,6 +65,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) :
_falseColorizeBySource = false;
_dataSourceID = UNKNOWN_NODE_ID;
_voxelServerCount = 0;
connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));
}
void VoxelSystem::nodeDeleted(VoxelNode* node) {
@ -994,6 +997,10 @@ public:
{ }
};
void VoxelSystem::cancelImport() {
_tree->cancelImport();
}
// "Remove" voxels from the tree that are not in view. We don't actually delete them,
// we remove them from the tree and place them into a holding area for later deletion
bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {

View file

@ -43,8 +43,6 @@ public:
void simulate(float deltaTime) { };
void render(bool texture);
VoxelTree* getVoxelTree () const {return _tree;}
unsigned long getVoxelsUpdated () const {return _voxelsUpdated;};
unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;};
@ -91,6 +89,10 @@ public:
virtual void nodeAdded(Node* node);
virtual void nodeKilled(Node* node);
signals:
void importSize(float x, float y, float z);
void importProgress(int progress);
public slots:
void collectStatsForTreesAndVBOs();
@ -104,6 +106,8 @@ public slots:
void falseColorizeOccluded();
void falseColorizeOccludedV2();
void falseColorizeBySource();
void cancelImport();
protected:
float _treeScale;

View file

@ -159,19 +159,17 @@ int retrieveData(std::string filename, std::stringstream &ss) {
int type = file.peek();
if (type == 0x0A) {
std::cerr << "[DEBUG] Unzipped\n";
ss.flush();
ss << file;
return 0;
}
if (type == 0x1F) {
std::cerr << "[DEBUG] Zipped\n";
int ret = ungzip(file, ss);
return ret;
}
std::cerr << "[DEBUG] Neither\n";
std::cerr << "[DEBUG] Schematic compression type not recognize : " << type << std::endl;
return 1;
}

View file

@ -361,6 +361,8 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int
// skip bitstream to new startPoint
bitstreamAt += theseBytesRead;
bytesRead += theseBytesRead;
emit importProgress((100 * (bitstreamAt - bitstream)) / bufferSizeBytes);
}
this->voxelsBytesRead += bufferSizeBytes;
@ -1559,6 +1561,10 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp
bool VoxelTree::readFromSVOFile(const char* fileName) {
std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate);
if(file.is_open()) {
emit importSize(1.0f, 1.0f, 1.0f);
emit importProgress(0);
qDebug("loading file %s...\n", fileName);
// get file length....
@ -1572,6 +1578,8 @@ bool VoxelTree::readFromSVOFile(const char* fileName) {
readBitstreamToTree(entireFile, fileLength, args);
delete[] entireFile;
emit importProgress(100);
file.close();
return true;
}
@ -1585,6 +1593,9 @@ bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) {
return false;
}
emit importSize(1.0f, 1.0f, 1.0f);
emit importProgress(0);
const uint32_t* pixels;
if (pngImage.format() == QImage::Format_ARGB32) {
pixels = reinterpret_cast<const uint32_t*>(pngImage.constBits());
@ -1595,6 +1606,8 @@ bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) {
SquarePixelMap pixelMap = SquarePixelMap(pixels, pngImage.height());
pixelMap.addVoxelsToVoxelTree(this);
emit importProgress(100);
return true;
}
@ -1629,6 +1642,7 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) {
emit importSize(size * schematics.getWidth(),
size * schematics.getHeight(),
size * schematics.getLength());
emit importProgress(0);
for (int y = 0; y < schematics.getHeight(); ++y) {
for (int z = 0; z < schematics.getLength(); ++z) {

View file

@ -196,7 +196,7 @@ public:
signals:
void importSize(float x, float y, float z);
void importProgress(int progress); // emit an int between 0 and 100 reflecting the progress of the import
void importProgress(int progress);
public slots:
void cancelImport();