From f2305fd9690d1a41684c704cfb7e31577bf63d9e Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 9 Aug 2013 23:11:04 -0700 Subject: [PATCH 1/8] Added VoxelImporter class --- interface/src/Application.cpp | 3 +- interface/src/Application.h | 6 ++- interface/src/VoxelImporter.cpp | 76 +++++++++++++++++++++++++++++++++ interface/src/VoxelImporter.h | 37 ++++++++++++++++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 interface/src/VoxelImporter.cpp create mode 100644 interface/src/VoxelImporter.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 772908abe5..5d6b2d0bd5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -181,6 +181,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _justStarted(true), _particleSystemInitialized(false), _coolDemoParticleEmitter(-1), + _voxelImporter(_window), _wantToKillLocalVoxels(false), _frustumDrawingMode(FRUSTUM_DRAW_MODE_ALL), _viewFrustumOffsetYaw(-135.0), @@ -2033,7 +2034,7 @@ void Application::initMenu() { (_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true); voxelMenu->addAction("Export Voxels", this, SLOT(exportVoxels()), Qt::CTRL | Qt::Key_E); - voxelMenu->addAction("Import Voxels", this, SLOT(importVoxels()), Qt::CTRL | Qt::Key_I); + voxelMenu->addAction("Import Voxels", &_voxelImporter, SLOT(exec()), Qt::CTRL | Qt::Key_I); voxelMenu->addAction("Import Voxels to Clipboard", this, SLOT(importVoxelsToClipboard()), Qt::SHIFT | Qt::CTRL | Qt::Key_I); voxelMenu->addAction("Cut Voxels", this, SLOT(cutVoxels()), Qt::CTRL | Qt::Key_X); voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); diff --git a/interface/src/Application.h b/interface/src/Application.h index cb851c1dfc..ce5e1c6a8a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -38,6 +38,7 @@ #include "ToolsPalette.h" #include "ViewFrustum.h" #include "VoxelSystem.h" +#include "VoxelImporter.h" #include "Webcam.h" #include "PieMenu.h" #include "avatar/Avatar.h" @@ -326,8 +327,9 @@ private: Stars _stars; - VoxelSystem _voxels; - VoxelTree _clipboardTree; // if I copy/paste + VoxelSystem _voxels; + VoxelTree _clipboardTree; // if I copy/paste + VoxelImporter _voxelImporter; QByteArray _voxelsFilename; bool _wantToKillLocalVoxels; diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp new file mode 100644 index 0000000000..4c389540d2 --- /dev/null +++ b/interface/src/VoxelImporter.cpp @@ -0,0 +1,76 @@ +// +// VoxelImporter.cpp +// hifi +// +// Created by Clement Brisset on 8/9/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include "VoxelImporter.h" + +#include +#include +#include + +const QString WINDOW_NAME = QObject::tr("Import Voxels"); +const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview"); +const QString IMPORT_BUTTON_NAME = QObject::tr("Import"); +const QString IMPORT_TO_CLIPBOARD_BUTTON_NAME = QObject::tr("Import into clipboard"); +const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, " + "Square PNG, " + "Schematic Files " + "(*.svo *.png *.schematic)"); + +const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + +VoxelImporter::VoxelImporter(QWidget* parent) + : QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES), + _importButton (IMPORT_BUTTON_NAME , this), + _clipboardImportButton(IMPORT_TO_CLIPBOARD_BUTTON_NAME, this), + _previewBox (PREVIEW_CHECKBOX_STRING , this), + _previewBar (this), + _glPreview (this) { + + setOption(QFileDialog::DontUseNativeDialog, true); + setFileMode(QFileDialog::ExistingFile); + setViewMode(QFileDialog::Detail); + _previewBar.setVisible(false); + _glPreview.setVisible(false); + + QGridLayout* gridLayout = (QGridLayout*) layout(); + gridLayout->addWidget(&_importButton , 2, 2); + gridLayout->addWidget(&_clipboardImportButton, 2, 3); + gridLayout->addWidget(&_previewBox , 3, 3); + gridLayout->addWidget(&_previewBar , 0, 3); + gridLayout->addWidget(&_glPreview , 1, 3); + + + connect(&_importButton , SIGNAL(pressed()), this, SLOT(importVoxels())); + connect(&_clipboardImportButton, SIGNAL(pressed()), this, SLOT(importVoxelsToClipboard())); + connect(&_previewBox, SIGNAL(toggled(bool)), &_previewBar, SLOT(setVisible(bool))); + connect(&_previewBox, SIGNAL(toggled(bool)), &_glPreview , SLOT(setVisible(bool))); +} + +int VoxelImporter::exec() { + _previewBox.setChecked(false); + _previewBar.setVisible(false); + _glPreview.setVisible(false); + + return exec(); +} + + +void VoxelImporter::importVoxels() { + accept(); + qDebug("Congratulation, you imported a file.\n"); +} + +void VoxelImporter::importVoxelsToClipboard() { + accept(); + qDebug("Congratulation, you imported a file to the clipboard.\n"); + +} + +void VoxelImporter::preview(bool) { + +} diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h new file mode 100644 index 0000000000..a664788a82 --- /dev/null +++ b/interface/src/VoxelImporter.h @@ -0,0 +1,37 @@ +// +// VoxelImporter.h +// hifi +// +// Created by Clement Brisset on 8/9/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__VoxelImporter__ +#define __hifi__VoxelImporter__ + +#include +#include +#include +#include +#include + +class VoxelImporter : public QFileDialog { + Q_OBJECT +public: + VoxelImporter(QWidget* parent = NULL); + +public slots: + int exec(); + void importVoxels(); + void importVoxelsToClipboard(); + void preview(bool); + +private: + QPushButton _importButton; + QPushButton _clipboardImportButton; + QCheckBox _previewBox; + QProgressBar _previewBar; + QGLWidget _glPreview; +}; + +#endif /* defined(__hifi__VoxelImporter__) */ From 68a1c56ad6e567c6983131e46efaa7fca203c680 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Thu, 15 Aug 2013 17:21:23 -0700 Subject: [PATCH 2/8] More work on import interface --- interface/src/Application.cpp | 20 +-- interface/src/VoxelImporter.cpp | 120 ++++++++++-------- interface/src/VoxelImporter.h | 46 ++++--- interface/src/VoxelSystem.cpp | 16 +++ interface/src/VoxelSystem.h | 6 +- libraries/voxels/src/Tags.cpp | 160 ++++++++++++++++++++++- libraries/voxels/src/Tags.h | 5 +- libraries/voxels/src/VoxelTree.cpp | 196 ++++++----------------------- libraries/voxels/src/VoxelTree.h | 16 ++- 9 files changed, 336 insertions(+), 249 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 63578c78a7..2d15e7fc58 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1623,20 +1623,7 @@ void Application::importVoxelsToClipboard() { _clipboardTree.eraseAllVoxels(); if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - QImage pngImage = QImage(fileName); - if (pngImage.height() != pngImage.width()) { - qDebug("ERROR: Bad PNG size: height != width.\n"); - return; - } - - const uint32_t* pixels; - if (pngImage.format() == QImage::Format_ARGB32) { - pixels = reinterpret_cast(pngImage.constBits()); - } else { - QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); - pixels = reinterpret_cast(tmp.constBits()); - } - _clipboardTree.readFromSquareARGB32Pixels(pixels, pngImage.height()); + _clipboardTree.readFromSquareARGB32Pixels(fileName); } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { _clipboardTree.readFromSVOFile(fileName); } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { @@ -1696,7 +1683,7 @@ void Application::importVoxels() { pixels = reinterpret_cast(tmp.constBits()); } - importVoxels.readFromSquareARGB32Pixels(pixels, pngImage.height()); + importVoxels.readFromSquareARGB32Pixels(fileName); } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { extension = QString(".svo"); importVoxels.readFromSVOFile(fileName); @@ -1963,8 +1950,7 @@ void Application::initMenu() { (_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true); voxelMenu->addAction("Export Voxels", this, SLOT(exportVoxels()), Qt::CTRL | Qt::Key_E); - voxelMenu->addAction("Import Voxels", &_voxelImporter, SLOT(exec()), Qt::CTRL | Qt::Key_I); - voxelMenu->addAction("Import Voxels to Clipboard", this, SLOT(importVoxelsToClipboard()), Qt::SHIFT | Qt::CTRL | Qt::Key_I); + voxelMenu->addAction("Import Voxels", &_voxelImporter, SLOT(import()), Qt::CTRL | Qt::Key_I); voxelMenu->addAction("Cut Voxels", this, SLOT(cutVoxels()), Qt::CTRL | Qt::Key_X); voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); voxelMenu->addAction("Paste Voxels", this, SLOT(pasteVoxels()), Qt::CTRL | Qt::Key_V); diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 4c389540d2..488dd4b907 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -6,71 +6,85 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include "VoxelImporter.h" +#include -#include -#include -#include +#include +#include -const QString WINDOW_NAME = QObject::tr("Import Voxels"); -const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview"); -const QString IMPORT_BUTTON_NAME = QObject::tr("Import"); -const QString IMPORT_TO_CLIPBOARD_BUTTON_NAME = QObject::tr("Import into clipboard"); -const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, " - "Square PNG, " - "Schematic Files " - "(*.svo *.png *.schematic)"); +class LocalVoxelSystem : public VoxelSystem { +public: + LocalVoxelSystem() : VoxelSystem(1) {}; -const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + virtual void removeOutOfView() {}; +}; VoxelImporter::VoxelImporter(QWidget* parent) - : QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES), - _importButton (IMPORT_BUTTON_NAME , this), - _clipboardImportButton(IMPORT_TO_CLIPBOARD_BUTTON_NAME, this), - _previewBox (PREVIEW_CHECKBOX_STRING , this), - _previewBar (this), - _glPreview (this) { + : QObject(parent), + _voxelSystem(new LocalVoxelSystem()), + _importDialog(parent, _voxelSystem), + _currentTask(NULL), + _nextTask(NULL) { - setOption(QFileDialog::DontUseNativeDialog, true); - setFileMode(QFileDialog::ExistingFile); - setViewMode(QFileDialog::Detail); - _previewBar.setVisible(false); - _glPreview.setVisible(false); - - QGridLayout* gridLayout = (QGridLayout*) layout(); - gridLayout->addWidget(&_importButton , 2, 2); - gridLayout->addWidget(&_clipboardImportButton, 2, 3); - gridLayout->addWidget(&_previewBox , 3, 3); - gridLayout->addWidget(&_previewBar , 0, 3); - gridLayout->addWidget(&_glPreview , 1, 3); - - - connect(&_importButton , SIGNAL(pressed()), this, SLOT(importVoxels())); - connect(&_clipboardImportButton, SIGNAL(pressed()), this, SLOT(importVoxelsToClipboard())); - connect(&_previewBox, SIGNAL(toggled(bool)), &_previewBar, SLOT(setVisible(bool))); - connect(&_previewBox, SIGNAL(toggled(bool)), &_glPreview , SLOT(setVisible(bool))); + connect(&_importDialog, SIGNAL(previewActivated(QString)), SLOT(preImport(QString))); + connect(&_importDialog, SIGNAL(currentChanged(QString)) , SLOT(preImport(QString))); } -int VoxelImporter::exec() { - _previewBox.setChecked(false); - _previewBar.setVisible(false); - _glPreview.setVisible(false); +void VoxelImporter::import(const QString &filename) { + _importDialog.reset(); + _filename = filename; + _currentTask = NULL; + _nextTask = NULL; - return exec(); -} + if (_filename == "") { + _importDialog.exec(); + } -void VoxelImporter::importVoxels() { - accept(); - qDebug("Congratulation, you imported a file.\n"); -} - -void VoxelImporter::importVoxelsToClipboard() { - accept(); - qDebug("Congratulation, you imported a file to the clipboard.\n"); - } -void VoxelImporter::preview(bool) { +void VoxelImporter::preImport(const QString &filename) { + if (_importDialog.getWantPreview() && QFileInfo(filename).isFile()) { + _filename = filename; + + _nextTask = new ImportTask(_voxelSystem, _filename); + connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); + + _importDialog.reset(); + + if (_currentTask != NULL) { + _voxelSystem->getVoxelTree()->cancelImport(); + } else { + launchTask(); + } + } +} + +void VoxelImporter::launchTask() { + if (_nextTask != NULL) { + _voxelSystem->killLocalVoxels(); + _currentTask = _nextTask; + _nextTask = NULL; + QThreadPool::globalInstance()->start(_currentTask); + } else { + _currentTask = NULL; + } +} + +ImportTask::ImportTask(VoxelSystem* voxelSystem, const QString &filename) + : _voxelSystem(voxelSystem), + _filename(filename) { } + +void ImportTask::run() { + if (_filename.endsWith(".png", Qt::CaseInsensitive)) { + _voxelSystem->readFromSquareARGB32Pixels(_filename.toLocal8Bit().data()); + } 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())); + } else { + qDebug("[ERROR] Invalid file extension.\n"); + } +} diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index a664788a82..1e8f1a14ae 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -9,29 +9,45 @@ #ifndef __hifi__VoxelImporter__ #define __hifi__VoxelImporter__ -#include -#include -#include -#include -#include +#include +#include -class VoxelImporter : public QFileDialog { +#include +#include + +class ImportTask : public QObject, public QRunnable { + Q_OBJECT +public: + ImportTask(VoxelSystem* voxelSystem, const QString &filename); + void run(); + +private: + VoxelSystem* _voxelSystem; + QString _filename; +}; + +class VoxelImporter : public QObject { Q_OBJECT public: VoxelImporter(QWidget* parent = NULL); + void init(); + public slots: - int exec(); - void importVoxels(); - void importVoxelsToClipboard(); - void preview(bool); + void import(const QString &filename = ""); + void preImport(const QString &filename); + +private slots: + void launchTask(); private: - QPushButton _importButton; - QPushButton _clipboardImportButton; - QCheckBox _previewBox; - QProgressBar _previewBar; - QGLWidget _glPreview; + VoxelSystem* _voxelSystem; + ImportDialog _importDialog; + + QString _filename; + + ImportTask* _currentTask; + ImportTask* _nextTask; }; #endif /* defined(__hifi__VoxelImporter__) */ diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index becf9f868f..5509ca3a72 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -139,6 +139,22 @@ bool VoxelSystem::readFromSVOFile(const char* filename) { return result; } +bool VoxelSystem::readFromSquareARGB32Pixels(const char *filename) { + bool result = _tree->readFromSquareARGB32Pixels(filename); + if (result) { + setupNewVoxelsForDrawing(); + } + return result; +} + +bool VoxelSystem::readFromSchematicFile(const char* filename) { + bool result = _tree->readFromSchematicFile(filename); + if (result) { + setupNewVoxelsForDrawing(); + } + return result; +} + long int VoxelSystem::getVoxelsCreated() { return _tree->voxelsCreated; } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 94e2d42e5e..56c22dc02c 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -42,12 +42,16 @@ public: void simulate(float deltaTime) { }; void render(bool texture); - unsigned long getVoxelsUpdated() const {return _voxelsUpdated;}; + + VoxelTree* getVoxelTree () const {return _tree;} + unsigned long getVoxelsUpdated () const {return _voxelsUpdated;}; unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;}; void loadVoxelsFile(const char* fileName,bool wantColorRandomizer); void writeToSVOFile(const char* filename, VoxelNode* node) const; bool readFromSVOFile(const char* filename); + bool readFromSquareARGB32Pixels(const char* filename); + bool readFromSchematicFile(const char* filename); long int getVoxelsCreated(); long int getVoxelsColored(); diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index 7df6f227ad..914606ce07 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -159,14 +159,19 @@ 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) { - return ungzip(file, ss); + std::cerr << "[DEBUG] Zipped\n"; + int ret = ungzip(file, ss); + return ret; } + std::cerr << "[DEBUG] Neither\n"; return 1; } @@ -242,3 +247,156 @@ int ungzip(std::ifstream &file, std::stringstream &ss) { } +void computeBlockColor(int id, int data, int& red, int& green, int& blue, int& create) { + + switch (id) { + case 1: + case 14: + case 15: + case 16: + case 21: + case 56: + case 73: + case 74: + case 97: + case 129: red = 128; green = 128; blue = 128; break; + case 2: red = 77; green = 117; blue = 66; break; + case 3: + case 60: red = 116; green = 83; blue = 56; break; + case 4: red = 71; green = 71; blue = 71; break; + case 5: + case 125: red = 133; green = 94; blue = 62; break; + case 7: red = 35; green = 35; blue = 35; break; + case 8: + case 9: red = 100; green = 109; blue = 185; break; + case 10: + case 11: red = 192; green = 64; blue = 8; break; + case 12: red = 209; green = 199; blue = 155; break; + case 13: red = 96; green = 94; blue = 93; break; + case 17: red = 71; green = 56; blue = 35; break; + case 18: red = 76; green = 104; blue = 64; break; + case 19: red = 119; green = 119; blue = 37; break; + case 22: red = 22; green = 44; blue = 86; break; + case 23: + case 29: + case 33: + case 61: + case 62: + case 158: red = 61; green = 61; blue = 61; break; + case 24: red = 209; green = 202; blue = 156; break; + case 25: + case 58: + case 84: + case 137: red = 57; green = 38; blue = 25; break; + case 35: + switch (data) { + case 0: red = 234; green = 234; blue = 234; break; + case 1: red = 224; green = 140; blue = 84; break; + case 2: red = 185; green = 90; blue = 194; break; + case 3: red = 124; green = 152; blue = 208; break; + case 4: red = 165; green = 154; blue = 35; break; + case 5: red = 70; green = 187; blue = 61; break; + case 6: red = 206; green = 124; blue = 145; break; + case 7: red = 66; green = 66; blue = 66; break; + case 8: red = 170; green = 176; blue = 176; break; + case 9: red = 45; green = 108; blue = 35; break; + case 10: red = 130; green = 62; blue = 8; break; + case 11: red = 43; green = 51; blue = 29; break; + case 12: red = 73; green = 47; blue = 29; break; + case 13: red = 57; green = 76; blue = 36; break; + case 14: red = 165; green = 58; blue = 53; break; + case 15: red = 24; green = 24; blue = 24; break; + default: + create = 0; + break; + } + break; + case 41: red = 239; green = 238; blue = 105; break; + case 42: red = 146; green = 146; blue = 146; break; + case 43: + case 98: red = 161; green = 161; blue = 161; break; + case 44: + create = 3; + + switch (data) { + case 0: red = 161; green = 161; blue = 161; break; + case 1: red = 209; green = 202; blue = 156; break; + case 2: red = 133; green = 94; blue = 62; break; + case 3: red = 71; green = 71; blue = 71; break; + case 4: red = 121; green = 67; blue = 53; break; + case 5: red = 161; green = 161; blue = 161; break; + case 6: red = 45; green = 22; blue = 26; break; + case 7: red = 195; green = 192; blue = 185; break; + default: + create = 0; + break; + } + break; + case 45: red = 121; green = 67; blue = 53; break; + case 46: red = 118; green = 36; blue = 13; break; + case 47: red = 155; green = 127; blue = 76; break; + case 48: red = 61; green = 79; blue = 61; break; + case 49: red = 52; green = 41; blue = 74; break; + case 52: red = 12; green = 66; blue = 71; break; + case 53: + case 67: + case 108: + case 109: + case 114: + case 128: + case 134: + case 135: + case 136: + case 156: + create = 2; + + switch (id) { + case 53: + case 134: + case 135: + case 136: red = 133; green = 94; blue = 62; break; + case 67: red = 71; green = 71; blue = 71; break; + case 108: red = 121; green = 67; blue = 53; break; + case 109: red = 161; green = 161; blue = 161; break; + case 114: red = 45; green = 22; blue = 26; break; + case 128: red = 209; green = 202; blue = 156; break; + case 156: red = 195; green = 192; blue = 185; break; + default: + create = 0; + break; + } + break; + case 54: + case 95: + case 146: red = 155; green = 105; blue = 32; break; + case 57: red = 145; green = 219; blue = 215; break; + case 79: red = 142; green = 162; blue = 195; break; + case 80: red = 255; green = 255; blue = 255; break; + case 81: red = 8; green = 64; blue = 15; break; + case 82: red = 150; green = 155; blue = 166; break; + case 86: + case 91: red = 179; green = 108; blue = 17; break; + case 87: + case 153: red = 91; green = 31; blue = 30; break; + case 88: red = 68; green = 49; blue = 38; break; + case 89: red = 180; green = 134; blue = 65; break; + case 103: red = 141; green = 143; blue = 36; break; + case 110: red = 103; green = 92; blue = 95; break; + case 112: red = 45; green = 22; blue = 26; break; + case 121: red = 183; green = 178; blue = 129; break; + case 123: red = 101; green = 59; blue = 31; break; + case 124: red = 213; green = 178; blue = 123; break; + case 130: red = 38; green = 54; blue = 56; break; + case 133: red = 53; green = 84; blue = 85; break; + case 152: red = 131; green = 22; blue = 7; break; + case 155: red = 195; green = 192; blue = 185; break; + case 159: red = 195; green = 165; blue = 150; break; + case 170: red = 168; green = 139; blue = 15; break; + case 172: red = 140; green = 86; blue = 61; break; + case 173: red = 9; green = 9; blue = 9; break; + default: + create = 0; + break; + } +} + diff --git a/libraries/voxels/src/Tags.h b/libraries/voxels/src/Tags.h index a005095142..9888190b14 100644 --- a/libraries/voxels/src/Tags.h +++ b/libraries/voxels/src/Tags.h @@ -29,8 +29,9 @@ #define TAG_Compound 10 #define TAG_Int_Array 11 -int retrieveData(std::string filename, std::stringstream &ss); -int ungzip(std::ifstream &file, std::stringstream &ss); +int retrieveData(std::string filename, std::stringstream &ss); +int ungzip(std::ifstream &file, std::stringstream &ss); +void computeBlockColor(int id, int data, int& r, int& g, int& b, int& create); class Tag { public: diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index c0fcee02dd..146e013cf6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "CoverageMap.h" #include "GeometryUtil.h" @@ -48,7 +49,8 @@ VoxelTree::VoxelTree(bool shouldReaverage) : voxelsColoredStats(100), voxelsBytesReadStats(100), _isDirty(true), - _shouldReaverage(shouldReaverage) { + _shouldReaverage(shouldReaverage), + _stopImport(false) { rootNode = new VoxelNode(); } @@ -1576,15 +1578,29 @@ bool VoxelTree::readFromSVOFile(const char* fileName) { return false; } -bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension) { - SquarePixelMap pixelMap = SquarePixelMap(pixels, dimension); +bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) { + QImage pngImage = QImage(filename); + if (pngImage.height() != pngImage.width()) { + qDebug("ERROR: Bad PNG size: height != width.\n"); + return false; + } + + const uint32_t* pixels; + if (pngImage.format() == QImage::Format_ARGB32) { + pixels = reinterpret_cast(pngImage.constBits()); + } else { + QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); + pixels = reinterpret_cast(tmp.constBits()); + } + + SquarePixelMap pixelMap = SquarePixelMap(pixels, pngImage.height()); pixelMap.addVoxelsToVoxelTree(this); return true; } bool VoxelTree::readFromSchematicFile(const char *fileName) { std::stringstream ss; - int err = retrieveData(fileName, ss); + int err = retrieveData(std::string(fileName), ss); if (err && ss.get() != TAG_Compound) { qDebug("[ERROR] Invalid schematic file.\n"); return false; @@ -1593,10 +1609,12 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { ss.get(); TagCompound schematics(ss); if (!schematics.getBlocksId() || !schematics.getBlocksData()) { - qDebug("[ERROR] Invalid schematic file.\n"); + qDebug("[ERROR] Invalid schematic data.\n"); return false; } + _stopImport = false; + int max = (schematics.getWidth() > schematics.getLength()) ? schematics.getWidth() : schematics.getLength(); max = (max > schematics.getHeight()) ? max : schematics.getHeight(); @@ -1608,9 +1626,21 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { int red = 128, green = 128, blue = 128; int count = 0; + emit importSize(size * schematics.getWidth(), + size * schematics.getHeight(), + size * schematics.getLength()); + for (int y = 0; y < schematics.getHeight(); ++y) { for (int z = 0; z < schematics.getLength(); ++z) { + emit importProgress((int) 100 * (y * schematics.getLength() + z) / (schematics.getHeight() * schematics.getLength())); + for (int x = 0; x < schematics.getWidth(); ++x) { + if (_stopImport) { + qDebug("[DEBUG] Canceled import at %d voxels.\n", count); + _stopImport = false; + return true; + } + int pos = ((y * schematics.getLength()) + z) * schematics.getWidth() + x; int id = schematics.getBlocksId()[pos]; int data = schematics.getBlocksData()[pos]; @@ -1656,6 +1686,7 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { } } + emit importProgress(100); qDebug("Created %d voxels from minecraft import.\n", count); return true; @@ -1747,155 +1778,6 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin } } -void VoxelTree::computeBlockColor(int id, int data, int& red, int& green, int& blue, int& create) { - - switch (id) { - case 1: - case 14: - case 15: - case 16: - case 21: - case 56: - case 73: - case 74: - case 97: - case 129: red = 128; green = 128; blue = 128; break; - case 2: red = 77; green = 117; blue = 66; break; - case 3: - case 60: red = 116; green = 83; blue = 56; break; - case 4: red = 71; green = 71; blue = 71; break; - case 5: - case 125: red = 133; green = 94; blue = 62; break; - case 7: red = 35; green = 35; blue = 35; break; - case 8: - case 9: red = 100; green = 109; blue = 185; break; - case 10: - case 11: red = 192; green = 64; blue = 8; break; - case 12: red = 209; green = 199; blue = 155; break; - case 13: red = 96; green = 94; blue = 93; break; - case 17: red = 71; green = 56; blue = 35; break; - case 18: red = 76; green = 104; blue = 64; break; - case 19: red = 119; green = 119; blue = 37; break; - case 22: red = 22; green = 44; blue = 86; break; - case 23: - case 29: - case 33: - case 61: - case 62: - case 158: red = 61; green = 61; blue = 61; break; - case 24: red = 209; green = 202; blue = 156; break; - case 25: - case 58: - case 84: - case 137: red = 57; green = 38; blue = 25; break; - case 35: - switch (data) { - case 0: red = 234; green = 234; blue = 234; break; - case 1: red = 224; green = 140; blue = 84; break; - case 2: red = 185; green = 90; blue = 194; break; - case 3: red = 124; green = 152; blue = 208; break; - case 4: red = 165; green = 154; blue = 35; break; - case 5: red = 70; green = 187; blue = 61; break; - case 6: red = 206; green = 124; blue = 145; break; - case 7: red = 66; green = 66; blue = 66; break; - case 8: red = 170; green = 176; blue = 176; break; - case 9: red = 45; green = 108; blue = 35; break; - case 10: red = 130; green = 62; blue = 8; break; - case 11: red = 43; green = 51; blue = 29; break; - case 12: red = 73; green = 47; blue = 29; break; - case 13: red = 57; green = 76; blue = 36; break; - case 14: red = 165; green = 58; blue = 53; break; - case 15: red = 24; green = 24; blue = 24; break; - default: - create = 0; - break; - } - break; - case 41: red = 239; green = 238; blue = 105; break; - case 42: red = 146; green = 146; blue = 146; break; - case 43: - case 98: red = 161; green = 161; blue = 161; break; - case 44: - create = 3; - - switch (data) { - case 0: red = 161; green = 161; blue = 161; break; - case 1: red = 209; green = 202; blue = 156; break; - case 2: red = 133; green = 94; blue = 62; break; - case 3: red = 71; green = 71; blue = 71; break; - case 4: red = 121; green = 67; blue = 53; break; - case 5: red = 161; green = 161; blue = 161; break; - case 6: red = 45; green = 22; blue = 26; break; - case 7: red = 195; green = 192; blue = 185; break; - default: - create = 0; - break; - } - break; - case 45: red = 121; green = 67; blue = 53; break; - case 46: red = 118; green = 36; blue = 13; break; - case 47: red = 155; green = 127; blue = 76; break; - case 48: red = 61; green = 79; blue = 61; break; - case 49: red = 52; green = 41; blue = 74; break; - case 52: red = 12; green = 66; blue = 71; break; - case 53: - case 67: - case 108: - case 109: - case 114: - case 128: - case 134: - case 135: - case 136: - case 156: - create = 2; - - switch (id) { - case 53: - case 134: - case 135: - case 136: red = 133; green = 94; blue = 62; break; - case 67: red = 71; green = 71; blue = 71; break; - case 108: red = 121; green = 67; blue = 53; break; - case 109: red = 161; green = 161; blue = 161; break; - case 114: red = 45; green = 22; blue = 26; break; - case 128: red = 209; green = 202; blue = 156; break; - case 156: red = 195; green = 192; blue = 185; break; - default: - create = 0; - break; - } - break; - case 54: - case 95: - case 146: red = 155; green = 105; blue = 32; break; - case 57: red = 145; green = 219; blue = 215; break; - case 79: red = 142; green = 162; blue = 195; break; - case 80: red = 255; green = 255; blue = 255; break; - case 81: red = 8; green = 64; blue = 15; break; - case 82: red = 150; green = 155; blue = 166; break; - case 86: - case 91: red = 179; green = 108; blue = 17; break; - case 87: - case 153: red = 91; green = 31; blue = 30; break; - case 88: red = 68; green = 49; blue = 38; break; - case 89: red = 180; green = 134; blue = 65; break; - case 103: red = 141; green = 143; blue = 36; break; - case 110: red = 103; green = 92; blue = 95; break; - case 112: red = 45; green = 22; blue = 26; break; - case 121: red = 183; green = 178; blue = 129; break; - case 123: red = 101; green = 59; blue = 31; break; - case 124: red = 213; green = 178; blue = 123; break; - case 130: red = 38; green = 54; blue = 56; break; - case 133: red = 53; green = 84; blue = 85; break; - case 152: red = 131; green = 22; blue = 7; break; - case 155: red = 195; green = 192; blue = 185; break; - case 159: red = 195; green = 165; blue = 150; break; - case 170: red = 168; green = 139; blue = 15; break; - case 172: red = 140; green = 86; blue = 61; break; - case 173: red = 9; green = 9; blue = 9; break; - default: - create = 0; - break; - } -} \ No newline at end of file +void VoxelTree::cancelImport() { + _stopImport = true; +} diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index f27543caa8..7bdfcc68af 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -19,6 +19,8 @@ #include "VoxelNodeBag.h" #include "VoxelSceneStats.h" +#include + // Callback function, for recuseTreeWithOperation typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; @@ -112,7 +114,8 @@ public: {} }; -class VoxelTree { +class VoxelTree : public QObject { + Q_OBJECT public: // when a voxel is created in the tree (object new'd) long voxelsCreated; @@ -172,9 +175,8 @@ public: void writeToSVOFile(const char* filename, VoxelNode* node = NULL) const; bool readFromSVOFile(const char* filename); // reads voxels from square image with alpha as a Y-axis - bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); + bool readFromSquareARGB32Pixels(const char *filename); bool readFromSchematicFile(const char* filename); - void computeBlockColor(int id, int data, int& r, int& g, int& b, int& create); unsigned long getVoxelCount(); @@ -192,6 +194,13 @@ public: RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData); +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 + +public slots: + void cancelImport(); + private: void deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraData); @@ -209,6 +218,7 @@ private: bool _isDirty; unsigned long int _nodesChangedFromBitstream; bool _shouldReaverage; + bool _stopImport; }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From 2eb29ee56bd43af5fff52e79a4ca0f65095a5add Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 16 Aug 2013 10:21:12 -0700 Subject: [PATCH 3/8] Added ImportDialog.* --- interface/src/ImportDialog.cpp | 192 +++++++++++++++++++++++++++++++++ interface/src/ImportDialog.h | 50 +++++++++ 2 files changed, 242 insertions(+) create mode 100644 interface/src/ImportDialog.cpp create mode 100644 interface/src/ImportDialog.h diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp new file mode 100644 index 0000000000..49bdef0b81 --- /dev/null +++ b/interface/src/ImportDialog.cpp @@ -0,0 +1,192 @@ +// +// ImportDialog.cpp +// hifi +// +// Created by Clement Brisset on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +#include "ImportDialog.h" + +#include +#include + +const QString WINDOW_NAME = QObject::tr("Import Voxels"); +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, " + "Square PNG, " + "Schematic Files " + "(*.svo *.png *.schematic)"); + +const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + +const glm::vec3 UP = glm::vec3(0, 1, 0); +const float ANGULAR_RATE = 0.02f; + +class GLWidget : public QGLWidget { +public: + GLWidget(QWidget* parent = NULL, VoxelSystem* voxelSystem = NULL); + void setDraw(bool draw) {_draw = draw;} + void setTargetCenter(glm::vec3 targetCenter) {_targetCenter = targetCenter;} + +protected: + virtual void initializeGL(); + virtual void resizeGL(int w, int h); + virtual void paintGL(); + +private: + VoxelSystem* _voxelSystem; + + bool _draw; + + float _a; + float _h; + glm::vec3 _targetCenter; +}; + +GLWidget::GLWidget(QWidget *parent, VoxelSystem *voxelSystem) + : QGLWidget(parent), + _voxelSystem(voxelSystem), + _draw(false), + _a(0.0f), + _h(0.0f), + _targetCenter(0.5f, 0.5f, 0.5f) { +} + +void GLWidget::initializeGL() { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel (GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + if(_voxelSystem) { + _voxelSystem->init(); + } + +} + +void GLWidget::resizeGL(int w, int h) { + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, (float) w / h, 0.25f, 500); +} + +void GLWidget::paintGL() { + glEnable(GL_LINE_SMOOTH); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + 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), + _targetCenter.x, _targetCenter.y, _targetCenter.z, + UP.x, UP.y, UP.z); + + + if (_draw && _voxelSystem) { + glBegin(GL_LINES); + glColor3d(1, 1 ,1); + glVertex3d(0, 0, 0); + glVertex3d(1, 0, 0); + + glVertex3d(0, 0, 0); + glVertex3d(0, 1, 0); + + glVertex3d(0, 0, 0); + glVertex3d(0, 0, 1); + + + glColor3d(0.4f, 0.4f ,0.4f); + 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); + glVertex3d(2 * _targetCenter.x, 0 , 2 * _targetCenter.z); + + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z); + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 0 ); + glEnd(); + + _voxelSystem->render(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)) { + + setOption(QFileDialog::DontUseNativeDialog, true); + setFileMode(QFileDialog::ExistingFile); + setViewMode(QFileDialog::Detail); + + QGridLayout* gridLayout = (QGridLayout*) layout(); + gridLayout->addWidget(&_clipboardImportBox, 2, 3); + gridLayout->addWidget(&_previewBox , 3, 3); + gridLayout->addWidget(&_previewBar , 0, 3); + gridLayout->addWidget(_glPreview , 1, 3); + gridLayout->setColumnStretch(3, 1); + + _previewBar.setVisible(false); + _previewBar.setRange(0, 100); + _previewBar.setValue(0); + + 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))); +} + +int ImportDialog::exec() { + _previewBox.setChecked(false); + _previewBar.setVisible(false); + + int ret = QFileDialog::exec(); + + + ((GLWidget*) _glPreview)->setDraw(false); + _glTimer.stop(); + _glPreview->updateGL(); + + return ret; +} + +void ImportDialog::setGLCamera(float x, float y, float z) { + ((GLWidget*) _glPreview)->setTargetCenter(glm::vec3(x, y, z) / 2.0f); +} + +void ImportDialog::reset() { + _previewBar.setValue(0); +} + +void ImportDialog::preview(bool wantPreview) { + _previewBar.setValue(0); + _previewBar.setVisible(wantPreview); + ((GLWidget*) _glPreview)->setDraw(wantPreview); + + if (wantPreview) { + emit previewActivated(_currentFile); + _glTimer.start(); + } else { + _glTimer.stop(); + _glPreview->updateGL(); + } +} + +void ImportDialog::saveCurrentFile(QString filename) { + _currentFile = filename; +} + +void ImportDialog::timer() { + _glPreview->updateGL(); + _glTimer.start(16); +} diff --git a/interface/src/ImportDialog.h b/interface/src/ImportDialog.h new file mode 100644 index 0000000000..013a291af3 --- /dev/null +++ b/interface/src/ImportDialog.h @@ -0,0 +1,50 @@ +// +// ImportDialog.h +// hifi +// +// Created by Clement Brisset on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__ImportDialog__ +#define __hifi__ImportDialog__ + +#include + +#include +#include +#include +#include +#include +#include + +class ImportDialog : public QFileDialog { + Q_OBJECT +public: + ImportDialog(QWidget* parent = NULL, VoxelSystem* voxelSystem = NULL); + + bool getWantPreview() const { return _previewBox.isChecked(); } + void reset(); + +signals: + void previewActivated(QString); + +public slots: + int exec(); + void setGLCamera(float x, float y, float z); + +private slots: + void preview(bool preview); + void saveCurrentFile(QString); + void timer(); + +private: + QString _currentFile; + QCheckBox _clipboardImportBox; + QCheckBox _previewBox; + QProgressBar _previewBar; + QGLWidget* _glPreview; + QTimer _glTimer; +}; + +#endif /* defined(__hifi__ImportDialog__) */ From 24531fdd107a720236fa6b74cf3f53bb85f4cc0b Mon Sep 17 00:00:00 2001 From: atlante45 Date: Mon, 19 Aug 2013 15:54:51 -0700 Subject: [PATCH 4/8] Dialogbox for import fully functionnal --- interface/src/Application.cpp | 24 +++-- interface/src/Application.h | 2 +- interface/src/ImportDialog.cpp | 136 ++++++++++++++++++++++------- interface/src/ImportDialog.h | 15 +++- interface/src/Menu.cpp | 7 +- interface/src/VoxelImporter.cpp | 119 ++++++++++++++++++++----- interface/src/VoxelImporter.h | 23 +++-- interface/src/VoxelSystem.cpp | 7 ++ interface/src/VoxelSystem.h | 8 +- libraries/voxels/src/Tags.cpp | 4 +- libraries/voxels/src/VoxelTree.cpp | 14 +++ libraries/voxels/src/VoxelTree.h | 2 +- 12 files changed, 275 insertions(+), 86 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a9364a68d2..4d5e548f17 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -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) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 26dcb67733..748642a428 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -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; diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index 49bdef0b81..57b37ca443 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -9,8 +9,10 @@ #include #include +#include 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(); diff --git a/interface/src/ImportDialog.h b/interface/src/ImportDialog.h index 013a291af3..f3c1934760 100644 --- a/interface/src/ImportDialog.h +++ b/interface/src/ImportDialog.h @@ -18,20 +18,30 @@ #include #include +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; }; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ee4cd36b16..181b109bfd 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -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; } -} \ No newline at end of file +} diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 488dd4b907..4dbabe129f 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -11,11 +11,21 @@ #include #include +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"); } diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index 1e8f1a14ae..be39123367 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -15,33 +15,30 @@ #include #include -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; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 843d02790a..c1e7f3f06e 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -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) { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index f45398a96b..aef1bedd6a 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -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; diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index 914606ce07..32d717cc6b 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -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; } diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 146e013cf6..31b7e30b87 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -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(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) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 7bdfcc68af..e988b3f3e0 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -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(); From 27b03382944ca0fc067eb61020adb7542a4c9c45 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 10:31:56 -0700 Subject: [PATCH 5/8] Fixed clipboard not being previewed --- interface/src/VoxelImporter.cpp | 5 +++-- interface/src/VoxelSystem.cpp | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 095110eb35..d292766fc1 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -70,7 +70,9 @@ void VoxelImporter::reset() { } int VoxelImporter::exec() { - if (!_initialized) { + reset(); + + if (_initialized) { _voxelSystem->init(); _importViewFrustum.setKeyholeRadius(100000.0f); _importViewFrustum.calculate(); @@ -78,7 +80,6 @@ int VoxelImporter::exec() { _initialized = true; } - reset(); int ret = _importDialog.exec(); if (!ret) { diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 37f7a49c6b..729bc65745 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1314,6 +1314,7 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destinationTree, bool rebaseToRoot) { _tree->copySubTreeIntoNewTree(startNode, destinationTree->_tree, rebaseToRoot); + destinationTree->setupNewVoxelsForDrawing(); } void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) { From 867303e673857d27c1a33cb5f8602a514b53cad2 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 11:33:10 -0700 Subject: [PATCH 6/8] Code cleanup --- interface/src/Application.cpp | 180 ++--------------------------- interface/src/Application.h | 1 - interface/src/ImportDialog.cpp | 2 +- interface/src/VoxelImporter.cpp | 7 +- libraries/voxels/src/VoxelTree.cpp | 2 - 5 files changed, 16 insertions(+), 176 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7080463466..c3137e2d9b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1194,183 +1194,27 @@ void Application::exportVoxels() { _window->activateWindow(); } -const char* IMPORT_FILE_TYPES = "Sparse Voxel Octree Files, Square PNG, Schematic Files (*.svo *.png *.schematic)"; -void Application::importVoxelsToClipboard() { - QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); - QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Import Voxels to Clipboard"), desktopLocation, - tr(IMPORT_FILE_TYPES)); - - QByteArray fileNameAscii = fileNameString.toLocal8Bit(); - const char* fileName = fileNameAscii.data(); - - _clipboard.killLocalVoxels(); - if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - _clipboard.readFromSquareARGB32Pixels(fileName); - } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { - _clipboard.readFromSVOFile(fileName); - } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { - _clipboard.readFromSchematicFile(fileName); - } - - // restore the main window's active state - _window->activateWindow(); -} - void Application::importVoxels() { _pasteMode = false; if (_voxelImporter.exec()) { qDebug("[DEBUG] Import succedded.\n"); - _pasteMode = true; + + if (_voxelImporter.getimportIntoClipboard()) { + _clipboard.killLocalVoxels(); + _voxelImporter.getVoxelSystem()->copySubTreeIntoNewTree( + _voxelImporter.getVoxelSystem()->getVoxelAt(0, 0, 0, 1), + &_clipboard, + true); + } else { + _pasteMode = true; + } + + } else { qDebug("[DEBUG] Import failed.\n"); } - return; - - QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); - - QStringList fileNameStringList = QFileDialog::getOpenFileNames(_glWidget, tr("Import Voxels"), desktopLocation, - tr(IMPORT_FILE_TYPES)); - - - // remember the "selected" voxel point before we do any importing... - float originalX = _mouseVoxel.x; - float originalZ = _mouseVoxel.z; - - const int PNG_TYPE_NAME_LENGTH = 4; - const int SVO_TYPE_NAME_LENGTH = 4; - const int SCH_TYPE_NAME_LENGTH = 10; - - // assume this is where we'll place it if filename doesn't have tiling - int unspecifiedColumnNum = 1; - int unspecifiedRowNum = 1; - - // if they select multiple files, but they don't specify the tiling, we - // will tile them to this size - int unspecifiedSquare = (sqrt(fileNameStringList.size()) + 0.5); - qDebug("unspecifiedSquare: %d\n", unspecifiedSquare); - - for (int i = 0; i < fileNameStringList.size(); i++) { - QString fileNameString = fileNameStringList.at(i); - QString extension; - QByteArray fileNameAscii = fileNameString.toLocal8Bit(); - const char* fileName = fileNameAscii.data(); - - int fileTypeNameLength = 0; - VoxelTree importVoxels; - if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - extension = QString(".png"); - QImage pngImage = QImage(fileName); - fileTypeNameLength = PNG_TYPE_NAME_LENGTH; - if (pngImage.height() != pngImage.width()) { - qDebug("ERROR: Bad PNG size: height != width.\n"); - return; - } - - const uint32_t* pixels; - if (pngImage.format() == QImage::Format_ARGB32) { - pixels = reinterpret_cast(pngImage.constBits()); - } else { - QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); - pixels = reinterpret_cast(tmp.constBits()); - } - - importVoxels.readFromSquareARGB32Pixels(fileName); - } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { - extension = QString(".svo"); - importVoxels.readFromSVOFile(fileName); - fileTypeNameLength = SVO_TYPE_NAME_LENGTH; - } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { - extension = QString(".schematic"); - importVoxels.readFromSchematicFile(fileName); - fileTypeNameLength = SCH_TYPE_NAME_LENGTH; - } - - // Where we plan to place this - int columnNum = 1; - int rowNum = 1; - bool isTileLocationUnspecified = false; - - // If we're in multi-file mode, then look for tiling specification in the file name - if (fileNameStringList.size() > 1) { - int indexOfFirstPeriod = fileNameString.indexOf('.'); - - //qDebug("indexOfFirstPeriod: %d\n", indexOfFirstPeriod); - - // If the first period, is the extension, then this is not a grid name; - if (fileNameString.mid(indexOfFirstPeriod, fileNameString.length() - indexOfFirstPeriod) == extension) { - qDebug("not a valid grid name... treat like tile Location Unspecified\n"); - isTileLocationUnspecified = true; - } else { - QString fileCoord = fileNameString.mid(indexOfFirstPeriod + 1, - fileNameString.length() - indexOfFirstPeriod - fileTypeNameLength - 1); - - //qDebug() << "fileCoord: " << fileCoord << "\n"; - indexOfFirstPeriod = fileCoord.indexOf('.'); - - //qDebug("indexOfFirstPeriod: %d\n", indexOfFirstPeriod); - - QString columnNumString = fileCoord.right(fileCoord.length() - indexOfFirstPeriod - 1); - QString rowNumString = fileCoord.left(indexOfFirstPeriod); - - //qDebug() << "columnNumString: " << columnNumString << "\n"; - //qDebug() << "rowNumString: " << rowNumString << "\n"; - - columnNum = columnNumString.toFloat(); - rowNum = rowNumString.toFloat(); - - // If there are no "grid sections" in the filename, then we're going to get - if (columnNum < 1 || rowNum < 1) { - qDebug("not a valid grid name... treat like tile Location Unspecified\n"); - isTileLocationUnspecified = true; - } - } - } - - if (isTileLocationUnspecified) { - qDebug("tile Location is Unspecified... \n"); - columnNum = unspecifiedColumnNum; - rowNum = unspecifiedRowNum; - - unspecifiedColumnNum++; - if (unspecifiedColumnNum > unspecifiedSquare) { - unspecifiedColumnNum = 1; - unspecifiedRowNum++; - } - } - qDebug("columnNum: %d\t rowNum: %d\n", columnNum, rowNum); - - _mouseVoxel.x = originalX + (columnNum - 1) * _mouseVoxel.s; - _mouseVoxel.z = originalZ + (rowNum - 1) * _mouseVoxel.s; - - VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - - // Recurse the Import Voxels tree, where everything is root relative, and send all the colored voxels to - // the server as an set voxel message, this will also rebase the voxels to the new location - unsigned char* calculatedOctCode = NULL; - SendVoxelsOperationArgs args; - - // we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the - // voxel size/position details. - if (selectedNode) { - args.newBaseOctCode = selectedNode->getOctalCode(); - } else { - args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - } - - qDebug("column:%d, row:%d, voxel:%f,%f,%f,%f\n", columnNum, rowNum, _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s ); - - // send the insert/paste of these voxels - importVoxels.recurseTreeWithOperation(sendVoxelsOperation, &args); - _voxelEditSender.flushQueue(); - - if (calculatedOctCode) { - delete[] calculatedOctCode; - } - - } - // restore the main window's active state _window->activateWindow(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 01d5c22fa4..a4ae01b730 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -139,7 +139,6 @@ public slots: void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data); void exportVoxels(); void importVoxels(); - void importVoxelsToClipboard(); void cutVoxels(); void copyVoxels(); void togglePasteMode(); diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index 7308a44347..9c6653cc8a 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -134,7 +134,7 @@ void GLWidget::paintGL() { glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 0 ); glEnd(); - _voxelSystem->render(true); + _voxelSystem->render(false); } } diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index d292766fc1..7aa7dcb02a 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -48,7 +48,7 @@ VoxelImporter::~VoxelImporter() { connect(_currentTask, SIGNAL(destroyed()), _voxelSystem, SLOT(deleteLater())); _voxelSystem->cancelImport(); _currentTask = NULL; - } else { + } else if (_initialized) { delete _voxelSystem; } } @@ -70,15 +70,14 @@ void VoxelImporter::reset() { } int VoxelImporter::exec() { - reset(); - - if (_initialized) { + if (!_initialized) { _voxelSystem->init(); _importViewFrustum.setKeyholeRadius(100000.0f); _importViewFrustum.calculate(); _voxelSystem->setViewFrustum(&_importViewFrustum); _initialized = true; } + reset(); int ret = _importDialog.exec(); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 41ccc2f2c8..124d2f7fa6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1629,8 +1629,6 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { return false; } - _stopImport = false; - int max = (schematics.getWidth() > schematics.getLength()) ? schematics.getWidth() : schematics.getLength(); max = (max > schematics.getHeight()) ? max : schematics.getHeight(); From 9003a7d40b3fa39938e546a68b51901b430e327d Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 12:06:47 -0700 Subject: [PATCH 7/8] PR comments --- interface/src/Application.cpp | 4 +++- interface/src/VoxelImporter.cpp | 29 +++++++++++++---------------- interface/src/VoxelImporter.h | 4 ++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c3137e2d9b..dbb2170150 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -81,6 +81,8 @@ const int STARTUP_JITTER_SAMPLES = PACKET_LENGTH_SAMPLES_PER_CHANNEL / 2; // Startup optimistically with small jitter buffer that // will start playback on the second received audio packet. +static const float CLIPBOARD_TREE_SCALE = 1.0f; + void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) { fprintf(stdout, "%s", message.toLocal8Bit().constData()); LogDisplay::instance.addMessage(message.toLocal8Bit().constData()); @@ -94,7 +96,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _frameCount(0), _fps(120.0f), _justStarted(true), - _clipboard(1), + _clipboard(CLIPBOARD_TREE_SCALE), _voxelImporter(_window), _wantToKillLocalVoxels(false), _audioScope(256, 200, true), diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 7aa7dcb02a..ef4eeafc4b 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -11,6 +11,7 @@ #include #include +static const int IMPORT_SYSTEM_SCALE = 1.0f; static const int MAX_VOXELS_PER_IMPORT = 2000000; class ImportTask : public QObject, public QRunnable { @@ -25,10 +26,10 @@ private: VoxelImporter::VoxelImporter(QWidget* parent) : QObject(parent), - _voxelSystem(new VoxelSystem(1, MAX_VOXELS_PER_IMPORT)), + _voxelSystem(IMPORT_SYSTEM_SCALE, MAX_VOXELS_PER_IMPORT), _initialized(false), _importWaiting(false), - _importDialog(parent, _voxelSystem), + _importDialog(parent, &_voxelSystem), _currentTask(NULL), _nextTask(NULL) { @@ -45,16 +46,13 @@ VoxelImporter::~VoxelImporter() { if (_currentTask) { disconnect(_currentTask, 0, 0, 0); - connect(_currentTask, SIGNAL(destroyed()), _voxelSystem, SLOT(deleteLater())); - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); _currentTask = NULL; - } else if (_initialized) { - delete _voxelSystem; } } void VoxelImporter::reset() { - _voxelSystem->killLocalVoxels(); + _voxelSystem.killLocalVoxels(); _importDialog.reset(); _filename = ""; _importWaiting = false; @@ -65,16 +63,15 @@ void VoxelImporter::reset() { } if (_currentTask) { - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); } } int VoxelImporter::exec() { if (!_initialized) { - _voxelSystem->init(); - _importViewFrustum.setKeyholeRadius(100000.0f); + _voxelSystem.init(); _importViewFrustum.calculate(); - _voxelSystem->setViewFrustum(&_importViewFrustum); + _voxelSystem.setViewFrustum(&_importViewFrustum); _initialized = true; } reset(); @@ -105,11 +102,11 @@ int VoxelImporter::preImport() { delete _nextTask; } - _nextTask = new ImportTask(_voxelSystem, _filename); + _nextTask = new ImportTask(&_voxelSystem, _filename); connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); if (_currentTask != NULL) { - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); } else { launchTask(); } @@ -141,12 +138,12 @@ int VoxelImporter::import() { delete _nextTask; } - _nextTask = new ImportTask(_voxelSystem, _filename); + _nextTask = new ImportTask(&_voxelSystem, _filename); connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); connect(_nextTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept())); if (_currentTask != NULL) { - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); } else { launchTask(); } @@ -156,7 +153,7 @@ int VoxelImporter::import() { void VoxelImporter::launchTask() { if (_nextTask != NULL) { - _voxelSystem->killLocalVoxels(); + _voxelSystem.killLocalVoxels(); _currentTask = _nextTask; _nextTask = NULL; QThreadPool::globalInstance()->start(_currentTask); diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index b5624ed07f..4ab230d6fb 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -25,7 +25,7 @@ public: void reset(); bool getImportWaiting() const { return _importWaiting; } - VoxelSystem* getVoxelSystem() const { return _voxelSystem; } + VoxelSystem* getVoxelSystem() { return &_voxelSystem; } bool getimportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); } public slots: @@ -37,7 +37,7 @@ private slots: void launchTask(); private: - VoxelSystem* _voxelSystem; + VoxelSystem _voxelSystem; ViewFrustum _importViewFrustum; bool _initialized; bool _importWaiting; From bda6e03117944fb67514fb882fb95d92dc3b63cd Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 12:11:34 -0700 Subject: [PATCH 8/8] Changed name of copySubTreeIntoNewTree destinationTree argument --- interface/src/VoxelSystem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 729bc65745..b0cbcf02c3 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1312,13 +1312,13 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo setupNewVoxelsForDrawing(); }; -void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destinationTree, bool rebaseToRoot) { - _tree->copySubTreeIntoNewTree(startNode, destinationTree->_tree, rebaseToRoot); - destinationTree->setupNewVoxelsForDrawing(); +void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destination, bool rebaseToRoot) { + _tree->copySubTreeIntoNewTree(startNode, destination->_tree, rebaseToRoot); + destination->setupNewVoxelsForDrawing(); } -void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) { - _tree->copySubTreeIntoNewTree(startNode, destinationTree, rebaseToRoot); +void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destination, bool rebaseToRoot) { + _tree->copySubTreeIntoNewTree(startNode, destination, rebaseToRoot); } void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) {