From 8faaa28bc135e2f3d2e2958c06d3049c2fbe7a0d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 7 Mar 2014 11:55:02 -0800 Subject: [PATCH] FST ploader base --- interface/src/Application.cpp | 4 + interface/src/Application.h | 5 + interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + libraries/shared/src/FstReader.cpp | 162 +++++++++++++++++++++++++++++ libraries/shared/src/FstReader.h | 37 +++++++ 6 files changed, 210 insertions(+) create mode 100644 libraries/shared/src/FstReader.cpp create mode 100644 libraries/shared/src/FstReader.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d0f924ecf5..28285cd7da 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3464,6 +3464,10 @@ void Application::reloadAllScripts() { } } +void Application::uploadFST() { + _fstReader.zip(); +} + void Application::removeScriptName(const QString& fileNameString) { _activeScripts.removeOne(fileNameString); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 0837ea92e3..a93d3d1352 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "Audio.h" #include "BandwidthMeter.h" @@ -246,6 +247,8 @@ public slots: void initAvatarAndViewFrustum(); void stopAllScripts(); void reloadAllScripts(); + + void uploadFST(); private slots: void timer(); @@ -473,6 +476,8 @@ private: TouchEvent _lastTouchEvent; Overlays _overlays; + + FstReader _fstReader; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 0586382cb9..0674826342 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -160,6 +160,7 @@ Menu::Menu() : QMenu* toolsMenu = addMenu("Tools"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor())); + addActionToQMenuAndActionHash(toolsMenu, MenuOption::FstUploader, 0, Application::getInstance(), SLOT(uploadFST())); QMenu* viewMenu = addMenu("View"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e2e0d3895a..204b93dd4a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -235,6 +235,7 @@ namespace MenuOption { const QString FirstPerson = "First Person"; const QString FrameTimer = "Show Timer"; const QString FrustumRenderMode = "Render Mode"; + const QString FstUploader = "Upload .fst file"; const QString Fullscreen = "Fullscreen"; const QString FullscreenMirror = "Fullscreen Mirror"; const QString GlowMode = "Cycle Glow Mode"; diff --git a/libraries/shared/src/FstReader.cpp b/libraries/shared/src/FstReader.cpp new file mode 100644 index 0000000000..fa2aebb2fe --- /dev/null +++ b/libraries/shared/src/FstReader.cpp @@ -0,0 +1,162 @@ +// +// FstReader.cpp +// hifi +// +// Created by Clément Brisset on 3/4/14. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#include +#include +#include +#include +#include +#include + +#include "FstReader.h" + +FstReader::FstReader() { + +} + + +bool FstReader::zip() { + // File Dialog + QString filename = QFileDialog::getOpenFileName(NULL, + "Select your .fst file ...", + QStandardPaths::writableLocation(QStandardPaths::DownloadLocation), + "*.fst"); + + // First we check the FST file + QFile fst(filename); + if (!fst.open(QFile::ReadOnly | QFile::Text)) { + qDebug() << "[ERROR] Could not open FST file : " << fst.fileName(); + return false; + } + qDebug() << "Reading FST file : " << QFileInfo(fst).filePath(); + + + QTemporaryDir tempRootDir(_zipDir.path() + "/" + QFileInfo(fst).baseName()); + QDir rootDir(tempRootDir.path()); + + // Let's read through the FST file + QTextStream stream(&fst); + QList line; + while (!stream.atEnd()) { + line = stream.readLine().split(QRegExp("[ =]"), QString::SkipEmptyParts); + if (line.isEmpty()) { + continue; + } + + // according to what is read, we modify the command + if (line.first() == filenameField) { + QFileInfo fbx(QFileInfo(fst).path() + "/" + line.at(1)); + if (!fbx.exists() || !fbx.isFile()) { // Check existence + qDebug() << "[ERROR] FBX file " << fbx.absoluteFilePath() << " doesn't exist."; + return false; + } else if (fbx.size() > MAX_FBX_SIZE) { // Check size + qDebug() << "[ERROR] FBX file " << fbx.absoluteFilePath() << " too big, over " << MAX_FBX_SIZE << " MB."; + return false; + } else { // Compress and copy + compressFile(fbx.filePath(), + rootDir.path() + "/" + line.at(1)); + } + } else if (line.first() == texdirField) { // Check existence + QFileInfo texdir(QFileInfo(fst).path() + "/" + line.at(1)); + if (!texdir.exists() || !texdir.isDir()) { + qDebug() << "[ERROR] Texture directory " << texdir.absolutePath() << " doesn't exist."; + return false; + } + QDir newTexdir(rootDir.canonicalPath() + "/" + line.at(1)); + if (!newTexdir.exists() && !rootDir.mkpath(line.at(1))) { // Create texdir + qDebug() << "[ERROR] Couldn't create " << line.at(1) << "."; + return false; + } + if (!addTextures(texdir, newTexdir)) { // Recursive compress and copy + return false; + } + } else if (line.first() == lodField) { + QFileInfo lod(QFileInfo(fst).path() + "/" + line.at(1)); + if (!lod.exists() || !lod.isFile()) { // Check existence + qDebug() << "[ERROR] FBX file " << lod.absoluteFilePath() << " doesn't exist."; + return false; + } else if (lod.size() > MAX_FBX_SIZE) { // Check size + qDebug() << "[ERROR] FBX file " << lod.absoluteFilePath() << " too big, over " << MAX_FBX_SIZE << " MB.";\ + return false; + } else { // Compress and copy + compressFile(lod.filePath(), rootDir.path() + "/" + line.at(1)); + } + } + } + + // Compress and copy the fst + compressFile(fst.fileName(), + rootDir.path() + "/" + QFileInfo(fst).fileName()); + + tempRootDir.setAutoRemove(false); + + return true; +} + +bool FstReader::addTextures(QFileInfo& texdir, QDir newTexdir) { + QStringList filter; + filter << "*.png" << "*.tiff" << "*.jpg" << "*.jpeg"; + + QFileInfoList list = QDir(texdir.filePath()).entryInfoList(filter, + QDir::Files | + QDir::AllDirs | + QDir::NoDotAndDotDot | + QDir::NoSymLinks); + foreach (QFileInfo info, list) { + if (info.isFile()) { + if (info.size() > MAX_TEXTURE_SIZE) { + qDebug() << "[ERROR] Texture " << info.absoluteFilePath() + << "too big, file over " << MAX_TEXTURE_SIZE << " Bytes."; + return false; + } + compressFile(info.canonicalFilePath(), newTexdir.path() + "/" + info.fileName()); + } else if (info.isDir()) { + if (newTexdir.mkdir(info.fileName())) { + qDebug() << "[ERROR] Couldn't create texdir."; + return false; + } + QDir texdirChild(newTexdir.canonicalPath() + "/" + info.fileName()); + if (!addTextures(info, QDir(info.canonicalFilePath()))) { + return false; + } + } else { + qDebug() << "[DEBUG] Invalid file type : " << info.filePath(); + } + } + + return true; +} + +bool FstReader::compressFile(const QString &inFileName, const QString &outFileName) { + QFile inFile(inFileName); + inFile.open(QIODevice::ReadOnly); + QByteArray buffer = inFile.readAll(); + + QFile outFile(outFileName); + if (!outFile.open(QIODevice::WriteOnly)) { + QDir(_zipDir.path()).mkpath(QFileInfo(outFileName).path()); + if (!outFile.open(QIODevice::WriteOnly)) { + qDebug() << "[ERROR] Could not compress " << inFileName << "."; + return false; + } + } + QDataStream out(&outFile); + out << qCompress(buffer); + + return true; +} + + + + + + + + + diff --git a/libraries/shared/src/FstReader.h b/libraries/shared/src/FstReader.h new file mode 100644 index 0000000000..44cd3f95cd --- /dev/null +++ b/libraries/shared/src/FstReader.h @@ -0,0 +1,37 @@ +// +// FstReader.h +// hifi +// +// Created by Clément Brisset on 3/4/14. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__FstReader__ +#define __hifi__FstReader__ + +#include +#include +#include + +static const QString filenameField = "filename"; +static const QString texdirField = "texdir"; +static const QString lodField = "lod"; + +static const int MAX_FBX_SIZE = 1024 * 1024; // 1 MB +static const int MAX_TEXTURE_SIZE = 1024 * 1024; // 1 MB + +class FstReader { +public: + FstReader(); + + bool zip(); + +private: + QTemporaryDir _zipDir; + + bool addTextures(QFileInfo& texdir, QDir newTexdir); + bool compressFile(const QString& inFileName, const QString& outFileName); +}; + +#endif /* defined(__hifi__FstReader__) */