forked from qt-creator/qt-creator
QmlDesigner: Move 3D asset import to puppet
Moved 3D asset import to puppet to ensure import always uses the correct version of the QtQuick3D. Fixes: QDS-3154 Change-Id: I630a833e7231383b87bf8b7214d3545d12de15ab Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -34,7 +34,13 @@ namespace QmlDesigner {
|
||||
class PuppetToCreatorCommand
|
||||
{
|
||||
public:
|
||||
enum Type { Edit3DToolState, Render3DView, ActiveSceneChanged, RenderModelNodePreviewImage, None };
|
||||
enum Type {
|
||||
Edit3DToolState,
|
||||
Render3DView,
|
||||
ActiveSceneChanged,
|
||||
RenderModelNodePreviewImage,
|
||||
Import3DSupport,
|
||||
None };
|
||||
|
||||
PuppetToCreatorCommand(Type type, const QVariant &data);
|
||||
PuppetToCreatorCommand() = default;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "import3d.h"
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
|
||||
#endif
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <QScopedPointer>
|
||||
|
||||
namespace Import3D
|
||||
{
|
||||
|
||||
void import3D(const QString &sourceAsset, const QString &outDir, int exitId, const QString &options)
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
QScopedPointer importer {new QSSGAssetImportManager};
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument optDoc = QJsonDocument::fromJson(options.toUtf8(), &error);
|
||||
|
||||
if (!optDoc.isNull() && optDoc.isObject()) {
|
||||
QString errorStr;
|
||||
QJsonObject optObj = optDoc.object();
|
||||
if (importer->importFile(sourceAsset, outDir, optObj.toVariantMap(), &errorStr)
|
||||
!= QSSGAssetImportManager::ImportState::Success) {
|
||||
qWarning() << __FUNCTION__ << "Failed to import 3D asset"
|
||||
<< sourceAsset << "with error:" << errorStr;
|
||||
} else {
|
||||
// Allow little time for file operations to finish
|
||||
QTimer::singleShot(2000, nullptr, [exitId]() {
|
||||
qApp->exit(exitId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
qWarning() << __FUNCTION__ << "Failed to parse import options:" << error.errorString();
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(sourceAsset)
|
||||
Q_UNUSED(outDir)
|
||||
Q_UNUSED(exitId)
|
||||
Q_UNUSED(options)
|
||||
qWarning() << __FUNCTION__ << "Failed to parse import options, Quick3DAssetImport not available";
|
||||
#endif
|
||||
QTimer::singleShot(0, nullptr, [exitId]() {
|
||||
// Negative exitId means import failure
|
||||
qApp->exit(-exitId);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
33
share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h
Normal file
33
share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace Import3D
|
||||
{
|
||||
void import3D(const QString &sourceAsset, const QString &outDir, int id, const QString &options);
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
HEADERS += $$PWD/import3d.h
|
||||
|
||||
SOURCES += $$PWD/import3d.cpp
|
||||
@@ -1,8 +1,14 @@
|
||||
INCLUDEPATH += $$PWD/
|
||||
|
||||
versionAtLeast(QT_VERSION, 5.15.0):qtHaveModule(quick3d) {
|
||||
versionAtLeast(QT_VERSION, 5.15.0) {
|
||||
qtHaveModule(quick3d) {
|
||||
QT *= quick3d-private
|
||||
DEFINES *= QUICK3D_MODULE
|
||||
}
|
||||
qtHaveModule(quick3dassetimport) {
|
||||
QT *= quick3dassetimport-private
|
||||
DEFINES *= IMPORT_QUICK3D_ASSETS
|
||||
}
|
||||
}
|
||||
|
||||
HEADERS += $$PWD/qt5nodeinstanceserver.h \
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
|
||||
#endif
|
||||
|
||||
// Uncomment to display FPS counter on the lower left corner of edit 3D view
|
||||
//#define FPS_COUNTER
|
||||
#ifdef FPS_COUNTER
|
||||
@@ -253,6 +257,37 @@ void Qt5InformationNodeInstanceServer::handleInputEvents()
|
||||
}
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::resolveImportSupport()
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
QSSGAssetImportManager importManager;
|
||||
const QHash<QString, QStringList> supportedExtensions = importManager.getSupportedExtensions();
|
||||
const QHash<QString, QVariantMap> supportedOptions = importManager.getAllOptions();
|
||||
|
||||
QVariantMap supportMap;
|
||||
|
||||
QVariantMap extMap;
|
||||
auto itExt = supportedExtensions.constBegin();
|
||||
while (itExt != supportedExtensions.constEnd()) {
|
||||
extMap.insert(itExt.key(), itExt.value());
|
||||
++itExt;
|
||||
}
|
||||
|
||||
QVariantMap optMap;
|
||||
auto itOpt = supportedOptions.constBegin();
|
||||
while (itOpt != supportedOptions.constEnd()) {
|
||||
optMap.insert(itOpt.key(), itOpt.value());
|
||||
++itOpt;
|
||||
}
|
||||
|
||||
supportMap.insert("options", optMap);
|
||||
supportMap.insert("extensions", extMap);
|
||||
nodeInstanceClient()->handlePuppetToCreatorCommand(
|
||||
{PuppetToCreatorCommand::Import3DSupport, QVariant(supportMap)});
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::createEditView3D()
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
@@ -1462,6 +1497,9 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
|
||||
|
||||
QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout,
|
||||
this, &Qt5InformationNodeInstanceServer::doRenderModelNodeImageView);
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
QTimer::singleShot(0, this, &Qt5InformationNodeInstanceServer::resolveImportSupport);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::sendChildrenChangedCommand(const QList<ServerNodeInstance> &childList)
|
||||
|
||||
@@ -131,6 +131,7 @@ private:
|
||||
void doRenderModelNode2DImageView();
|
||||
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
||||
void handleInputEvents();
|
||||
void resolveImportSupport();
|
||||
|
||||
void createAuxiliaryQuickView(const QUrl &url, RenderViewData &viewData);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ include (../interfaces/interfaces.pri)
|
||||
include (../types/types.pri)
|
||||
include (../qmlprivategate/qmlprivategate.pri)
|
||||
include (iconrenderer/iconrenderer.pri)
|
||||
include (import3d/import3d.pri)
|
||||
|
||||
SOURCES += $$PWD/qml2puppetmain.cpp
|
||||
RESOURCES += $$PWD/../qmlpuppet.qrc
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "iconrenderer/iconrenderer.h"
|
||||
#include "import3d/import3d.h"
|
||||
#include <qt5nodeinstanceclientproxy.h>
|
||||
|
||||
#include <QQmlComponent>
|
||||
@@ -152,12 +153,14 @@ int internalMain(QGuiApplication *application)
|
||||
|
||||
if (application->arguments().count() < 2
|
||||
|| (application->arguments().at(1) == "--readcapturedstream" && application->arguments().count() < 3)
|
||||
|| (application->arguments().at(1) == "--rendericon" && application->arguments().count() < 5)) {
|
||||
|| (application->arguments().at(1) == "--rendericon" && application->arguments().count() < 5)
|
||||
|| (application->arguments().at(1) == "--import3dAsset" && application->arguments().count() < 6)) {
|
||||
qDebug() << "Usage:\n";
|
||||
qDebug() << "--test";
|
||||
qDebug() << "--version";
|
||||
qDebug() << "--readcapturedstream <stream file> [control stream file]";
|
||||
qDebug() << "--rendericon <icon size> <icon file name> <icon source qml>";
|
||||
qDebug() << "--import3dAsset <source asset file name> <output dir> <id number> <import options JSON>";
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -220,6 +223,17 @@ int internalMain(QGuiApplication *application)
|
||||
return application->exec();
|
||||
}
|
||||
|
||||
if (application->arguments().at(1) == "--import3dAsset") {
|
||||
QString sourceAsset = application->arguments().at(2);
|
||||
QString outDir = application->arguments().at(3);
|
||||
int exitId = application->arguments().at(4).toInt();
|
||||
QString options = application->arguments().at(5);
|
||||
|
||||
Import3D::import3D(sourceAsset, outDir, exitId, options);
|
||||
|
||||
return application->exec();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_QT_BREAKPAD
|
||||
const QString libexecPath = QCoreApplication::applicationDirPath() + '/' + RELATIVE_LIBEXEC_PATH;
|
||||
QtSystemExceptionHandler systemExceptionHandler(libexecPath);
|
||||
|
||||
@@ -326,14 +326,6 @@ extend_qtc_plugin(QmlDesigner
|
||||
itemlibraryiconimageprovider.cpp itemlibraryiconimageprovider.h
|
||||
)
|
||||
|
||||
find_package(Qt5 COMPONENTS Quick3DAssetImport QUIET)
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
CONDITION TARGET Qt5::Quick3DAssetImport
|
||||
FEATURE_INFO "Qt Quick 3D asset import"
|
||||
DEPENDS Qt5::Quick3DAssetImportPrivate
|
||||
DEFINES IMPORT_QUICK3D_ASSETS
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/navigator
|
||||
SOURCES
|
||||
|
||||
@@ -199,6 +199,15 @@ void DesignerActionManager::registerAddResourceHandler(const AddResourceHandler
|
||||
m_addResourceHandler.append(handler);
|
||||
}
|
||||
|
||||
void DesignerActionManager::unregisterAddResourceHandlers(const QString &category)
|
||||
{
|
||||
for (int i = m_addResourceHandler.size() - 1; i >= 0 ; --i) {
|
||||
const AddResourceHandler &handler = m_addResourceHandler[i];
|
||||
if (handler.category == category)
|
||||
m_addResourceHandler.removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
void DesignerActionManager::registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler)
|
||||
{
|
||||
m_modelNodePreviewImageHandlers.append(handler);
|
||||
|
||||
@@ -129,6 +129,7 @@ public:
|
||||
|
||||
QList<AddResourceHandler> addResourceHandler() const;
|
||||
void registerAddResourceHandler(const AddResourceHandler &handler);
|
||||
void unregisterAddResourceHandlers(const QString &category);
|
||||
|
||||
void registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler);
|
||||
bool hasModelNodePreviewHandler(const ModelNode &node) const;
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
VPATH += $$PWD
|
||||
|
||||
qtHaveModule(quick3dassetimport) {
|
||||
QT *= quick3dassetimport-private
|
||||
DEFINES *= IMPORT_QUICK3D_ASSETS
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += itemlibraryview.h \
|
||||
$$PWD/itemlibraryiconimageprovider.h \
|
||||
|
||||
@@ -71,10 +71,13 @@ static const int rowHeight = 26;
|
||||
}
|
||||
|
||||
ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &importFiles,
|
||||
const QString &defaulTargetDirectory, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ItemLibraryAssetImportDialog),
|
||||
m_importer(this)
|
||||
const QString &defaulTargetDirectory,
|
||||
const QVariantMap &supportedExts,
|
||||
const QVariantMap &supportedOpts,
|
||||
QWidget *parent) :
|
||||
QDialog(parent)
|
||||
, ui(new Ui::ItemLibraryAssetImportDialog)
|
||||
, m_importer(this)
|
||||
{
|
||||
setModal(true);
|
||||
ui->setupUi(this);
|
||||
@@ -83,15 +86,24 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
||||
m_outputFormatter->setPlainTextEdit(ui->plainTextEdit);
|
||||
|
||||
// Skip unsupported assets
|
||||
bool skipSome = false;
|
||||
QHash<QString, bool> supportMap;
|
||||
for (const auto &file : importFiles) {
|
||||
if (m_importer.isQuick3DAsset(file))
|
||||
QString suffix = QFileInfo(file).suffix();
|
||||
if (!supportMap.contains(suffix)) {
|
||||
bool supported = false;
|
||||
for (const auto &exts : supportedExts) {
|
||||
if (exts.toStringList().contains(suffix)) {
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
supportMap.insert(suffix, supported);
|
||||
}
|
||||
if (supportMap[suffix])
|
||||
m_quick3DFiles << file;
|
||||
else
|
||||
skipSome = true;
|
||||
}
|
||||
|
||||
if (skipSome)
|
||||
if (m_quick3DFiles.size() != importFiles.size())
|
||||
addWarning("Cannot import 3D and other assets simultaneously. Skipping non-3D assets.");
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Import"));
|
||||
@@ -153,14 +165,12 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
||||
m_quick3DImportPath = candidatePath;
|
||||
|
||||
if (!m_quick3DFiles.isEmpty()) {
|
||||
const QHash<QString, QVariantMap> allOptions = m_importer.allOptions();
|
||||
const QHash<QString, QStringList> supportedExtensions = m_importer.supportedExtensions();
|
||||
QVector<QJsonObject> groups;
|
||||
|
||||
auto optIt = allOptions.constBegin();
|
||||
auto optIt = supportedOpts.constBegin();
|
||||
int optIndex = 0;
|
||||
while (optIt != allOptions.constEnd()) {
|
||||
QJsonObject options = QJsonObject::fromVariantMap(optIt.value());
|
||||
while (optIt != supportedOpts.constEnd()) {
|
||||
QJsonObject options = QJsonObject::fromVariantMap(qvariant_cast<QVariantMap>(optIt.value()));
|
||||
m_importOptions << options.value("options").toObject();
|
||||
groups << options.value("groups").toObject();
|
||||
const auto &exts = optIt.key().split(':');
|
||||
@@ -173,10 +183,10 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
||||
// Create tab for each supported extension group that also has files included in the import
|
||||
QMap<QString, int> tabMap; // QMap used for alphabetical order
|
||||
for (const auto &file : qAsConst(m_quick3DFiles)) {
|
||||
auto extIt = supportedExtensions.constBegin();
|
||||
auto extIt = supportedExts.constBegin();
|
||||
QString ext = QFileInfo(file).suffix().toLower();
|
||||
while (extIt != supportedExtensions.constEnd()) {
|
||||
if (!tabMap.contains(extIt.key()) && extIt.value().contains(ext)) {
|
||||
while (extIt != supportedExts.constEnd()) {
|
||||
if (!tabMap.contains(extIt.key()) && extIt.value().toStringList().contains(ext)) {
|
||||
tabMap.insert(extIt.key(), m_extToImportOptionsMap.value(ext));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,10 @@ class ItemLibraryAssetImportDialog : public QDialog
|
||||
|
||||
public:
|
||||
explicit ItemLibraryAssetImportDialog(const QStringList &importFiles,
|
||||
const QString &defaulTargetDirectory, QWidget *parent = nullptr);
|
||||
const QString &defaulTargetDirectory,
|
||||
const QVariantMap &supportedExts,
|
||||
const QVariantMap &supportedOpts,
|
||||
QWidget *parent = nullptr);
|
||||
~ItemLibraryAssetImportDialog();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -30,18 +30,15 @@
|
||||
#include "model.h"
|
||||
#include "puppetcreator.h"
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qdiriterator.h>
|
||||
#include <QtCore/qsavefile.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qtemporarydir.h>
|
||||
#include <QtWidgets/qapplication.h>
|
||||
#include <QtWidgets/qmessagebox.h>
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
|
||||
#endif
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QSaveFile>
|
||||
#include <QFile>
|
||||
#include <QLoggingCategory>
|
||||
#include <QTemporaryDir>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -53,9 +50,6 @@ namespace QmlDesigner {
|
||||
ItemLibraryAssetImporter::ItemLibraryAssetImporter(QObject *parent) :
|
||||
QObject (parent)
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
m_quick3DAssetImporter.reset(new QSSGAssetImportManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
ItemLibraryAssetImporter::~ItemLibraryAssetImporter() {
|
||||
@@ -73,7 +67,6 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
||||
reset();
|
||||
m_isImporting = true;
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
if (!m_tempDir->isValid()) {
|
||||
addError(tr("Could not create a temporary directory for import."));
|
||||
notifyFinished();
|
||||
@@ -85,24 +78,27 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
||||
parseFiles(inputFiles, options, extToImportOptionsMap);
|
||||
|
||||
if (!isCancelled()) {
|
||||
// Wait for icon generation processes to finish
|
||||
const auto parseData = m_parseData;
|
||||
for (const auto &pd : parseData) {
|
||||
if (!startImportProcess(pd)) {
|
||||
addError(tr("Failed to start import 3D asset process"),
|
||||
pd.sourceInfo.absoluteFilePath());
|
||||
m_parseData.remove(pd.importId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCancelled()) {
|
||||
// Wait for puppet processes to finish
|
||||
if (m_qmlPuppetProcesses.empty()) {
|
||||
finalizeQuick3DImport();
|
||||
postImport();
|
||||
} else {
|
||||
m_qmlPuppetCount = static_cast<int>(m_qmlPuppetProcesses.size());
|
||||
const QString progressTitle = tr("Generating icons.");
|
||||
const QString progressTitle = tr("Importing 3D assets.");
|
||||
addInfo(progressTitle);
|
||||
notifyProgress(0, progressTitle);
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(inputFiles)
|
||||
Q_UNUSED(importPath)
|
||||
Q_UNUSED(options)
|
||||
Q_UNUSED(extToImportOptionsMap)
|
||||
addError(tr("Importing 3D assets requires building against Qt Quick 3D module."));
|
||||
notifyFinished();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetImporter::isImporting() const
|
||||
@@ -135,67 +131,47 @@ void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &sr
|
||||
emit infoReported(infoMsg, srcPath);
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetImporter::isQuick3DAsset(const QString &fileName) const
|
||||
void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
static QStringList quick3DExt;
|
||||
if (quick3DExt.isEmpty()) {
|
||||
const auto exts = m_quick3DAssetImporter->getSupportedExtensions();
|
||||
for (const auto &ext : exts)
|
||||
quick3DExt << ext;
|
||||
Q_UNUSED(exitStatus)
|
||||
|
||||
++m_qmlImportFinishedCount;
|
||||
|
||||
m_qmlPuppetProcesses.erase(
|
||||
std::remove_if(m_qmlPuppetProcesses.begin(), m_qmlPuppetProcesses.end(),
|
||||
[&](const auto &entry) {
|
||||
return !entry || entry->state() == QProcess::NotRunning;
|
||||
}));
|
||||
|
||||
if (m_parseData.contains(-exitCode)) {
|
||||
const ParseData pd = m_parseData.take(-exitCode);
|
||||
addError(tr("Asset import process failed for: \"%1\"").arg(pd.sourceInfo.absoluteFilePath()));
|
||||
}
|
||||
|
||||
if (m_qmlImportFinishedCount == m_qmlPuppetCount) {
|
||||
notifyProgress(100);
|
||||
QTimer::singleShot(0, this, &ItemLibraryAssetImporter::postImport);
|
||||
} else {
|
||||
notifyProgress(int(100. * (double(m_qmlImportFinishedCount) / double(m_qmlPuppetCount))));
|
||||
}
|
||||
return quick3DExt.contains(QFileInfo(fileName).suffix().toLower());
|
||||
#else
|
||||
Q_UNUSED(fileName)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
QVariantMap ItemLibraryAssetImporter::supportedOptions(const QString &modelFile) const
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
return m_quick3DAssetImporter->getOptionsForFile(modelFile);
|
||||
#else
|
||||
Q_UNUSED(modelFile)
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
QHash<QString, QVariantMap> ItemLibraryAssetImporter::allOptions() const
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
return m_quick3DAssetImporter->getAllOptions();
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
QHash<QString, QStringList> ItemLibraryAssetImporter::supportedExtensions() const
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
return m_quick3DAssetImporter->getSupportedExtensions();
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
void ItemLibraryAssetImporter::iconProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
Q_UNUSED(exitCode)
|
||||
Q_UNUSED(exitStatus)
|
||||
|
||||
m_qmlPuppetProcesses.erase(
|
||||
std::remove_if(m_qmlPuppetProcesses.begin(), m_qmlPuppetProcesses.end(), [&](const auto &entry) {
|
||||
std::remove_if(m_qmlPuppetProcesses.begin(), m_qmlPuppetProcesses.end(),
|
||||
[&](const auto &entry) {
|
||||
return !entry || entry->state() == QProcess::NotRunning;
|
||||
}));
|
||||
|
||||
const QString progressTitle = tr("Generating icons.");
|
||||
if (m_qmlPuppetProcesses.empty()) {
|
||||
notifyProgress(100, progressTitle);
|
||||
finalizeQuick3DImport();
|
||||
notifyProgress(100);
|
||||
QTimer::singleShot(0, this, &ItemLibraryAssetImporter::finalizeQuick3DImport);
|
||||
} else {
|
||||
notifyProgress(int(100. * (1. - double(m_qmlPuppetCount) / double(m_qmlPuppetProcesses.size()))),
|
||||
progressTitle);
|
||||
notifyProgress(int(100. * (1. - (double(m_qmlPuppetProcesses.size()) / double(m_qmlPuppetCount)))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,14 +186,14 @@ void ItemLibraryAssetImporter::reset()
|
||||
m_isImporting = false;
|
||||
m_cancelled = false;
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
delete m_tempDir;
|
||||
m_tempDir = new QTemporaryDir;
|
||||
m_importFiles.clear();
|
||||
m_overwrittenImports.clear();
|
||||
m_qmlPuppetProcesses.clear();
|
||||
m_qmlPuppetCount = 0;
|
||||
#endif
|
||||
m_qmlImportFinishedCount = 0;
|
||||
m_parseData.clear();
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
||||
@@ -235,99 +211,86 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
||||
notifyProgress(qRound(quota * (count + value)), progressTitle);
|
||||
};
|
||||
for (const QString &file : filePaths) {
|
||||
if (isCancelled())
|
||||
return;
|
||||
if (isQuick3DAsset(file)) {
|
||||
int index = extToImportOptionsMap.value(QFileInfo(file).suffix());
|
||||
parseQuick3DAsset(file, options[index].toVariantMap());
|
||||
ParseData pd;
|
||||
pd.options = options[index];
|
||||
if (preParseQuick3DAsset(file, pd)) {
|
||||
pd.importId = ++m_importIdCounter;
|
||||
m_parseData.insert(pd.importId, pd);
|
||||
}
|
||||
notifyProgress(qRound(++count * quota), progressTitle);
|
||||
}
|
||||
notifyProgress(100, progressTitle);
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVariantMap &options)
|
||||
bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseData &pd)
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
addInfo(tr("Parsing 3D Model"), file);
|
||||
pd.targetDir = QDir(m_importPath);
|
||||
pd.outDir = QDir(m_tempDir->path());
|
||||
pd.sourceInfo = QFileInfo(file);
|
||||
pd.assetName = pd.sourceInfo.completeBaseName();
|
||||
|
||||
QString errorString;
|
||||
|
||||
QDir targetDir(m_importPath);
|
||||
QDir outDir(m_tempDir->path());
|
||||
QFileInfo sourceInfo(file);
|
||||
QString assetName = sourceInfo.completeBaseName();
|
||||
|
||||
if (!assetName.isEmpty()) {
|
||||
if (!pd.assetName.isEmpty()) {
|
||||
// Fix name so it plays nice with imports
|
||||
for (QChar ¤tChar : assetName) {
|
||||
for (QChar ¤tChar : pd.assetName) {
|
||||
if (!currentChar.isLetter() && !currentChar.isDigit())
|
||||
currentChar = QLatin1Char('_');
|
||||
}
|
||||
const QChar firstChar = assetName[0];
|
||||
const QChar firstChar = pd.assetName[0];
|
||||
if (firstChar.isDigit())
|
||||
assetName[0] = QLatin1Char('_');
|
||||
pd.assetName[0] = QLatin1Char('_');
|
||||
if (firstChar.isLower())
|
||||
assetName[0] = firstChar.toUpper();
|
||||
pd.assetName[0] = firstChar.toUpper();
|
||||
}
|
||||
|
||||
QString targetDirPath = targetDir.filePath(assetName);
|
||||
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
||||
|
||||
if (outDir.exists(assetName)) {
|
||||
addWarning(tr("Skipped import of duplicate asset: \"%1\"").arg(assetName));
|
||||
return;
|
||||
if (pd.outDir.exists(pd.assetName)) {
|
||||
addWarning(tr("Skipped import of duplicate asset: \"%1\"").arg(pd.assetName));
|
||||
return false;
|
||||
}
|
||||
|
||||
QString originalAssetName = assetName;
|
||||
if (targetDir.exists(assetName)) {
|
||||
pd.originalAssetName = pd.assetName;
|
||||
if (pd.targetDir.exists(pd.assetName)) {
|
||||
// If we have a file system with case insensitive filenames, assetName may be
|
||||
// different from the existing name. Modify assetName to ensure exact match to
|
||||
// the overwritten old asset capitalization
|
||||
const QStringList assetDirs = targetDir.entryList({assetName}, QDir::Dirs);
|
||||
const QStringList assetDirs = pd.targetDir.entryList({pd.assetName}, QDir::Dirs);
|
||||
if (assetDirs.size() == 1) {
|
||||
assetName = assetDirs[0];
|
||||
targetDirPath = targetDir.filePath(assetName);
|
||||
pd.assetName = assetDirs[0];
|
||||
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
||||
}
|
||||
if (!confirmAssetOverwrite(assetName)) {
|
||||
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(assetName));
|
||||
return;
|
||||
if (!confirmAssetOverwrite(pd.assetName)) {
|
||||
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(pd.assetName));
|
||||
return false;
|
||||
}
|
||||
m_overwrittenImports << targetDirPath;
|
||||
m_overwrittenImports << pd.targetDirPath;
|
||||
}
|
||||
|
||||
outDir.mkpath(assetName);
|
||||
pd.outDir.mkpath(pd.assetName);
|
||||
|
||||
if (!outDir.cd(assetName)) {
|
||||
if (!pd.outDir.cd(pd.assetName)) {
|
||||
addError(tr("Could not access temporary asset directory: \"%1\"")
|
||||
.arg(outDir.filePath(assetName)));
|
||||
return;
|
||||
.arg(pd.outDir.filePath(pd.assetName)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
addInfo(tr("Generating 3D assets for: \"%1\"").arg(targetDir.absoluteFilePath(assetName)));
|
||||
|
||||
if (m_quick3DAssetImporter->importFile(
|
||||
sourceInfo.absoluteFilePath(), outDir, options, &errorString)
|
||||
!= QSSGAssetImportManager::ImportState::Success) {
|
||||
addError(tr("Failed to import 3D asset with error: %1").arg(errorString),
|
||||
sourceInfo.absoluteFilePath());
|
||||
return;
|
||||
}
|
||||
|
||||
// The importer is reset after every import to avoid issues with it caching various things
|
||||
m_quick3DAssetImporter.reset(new QSSGAssetImportManager);
|
||||
|
||||
if (originalAssetName != assetName) {
|
||||
void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
||||
{
|
||||
QDir outDir = pd.outDir;
|
||||
if (pd.originalAssetName != pd.assetName) {
|
||||
// Fix the generated qml file name
|
||||
const QString assetQml = originalAssetName + ".qml";
|
||||
const QString assetQml = pd.originalAssetName + ".qml";
|
||||
if (outDir.exists(assetQml))
|
||||
outDir.rename(assetQml, assetName + ".qml");
|
||||
outDir.rename(assetQml, pd.assetName + ".qml");
|
||||
}
|
||||
|
||||
QHash<QString, QString> assetFiles;
|
||||
const int outDirPathSize = outDir.path().size();
|
||||
auto insertAsset = [&](const QString &filePath) {
|
||||
QString targetPath = filePath.mid(outDirPathSize);
|
||||
targetPath.prepend(targetDirPath);
|
||||
targetPath.prepend(pd.targetDirPath);
|
||||
assetFiles.insert(filePath, targetPath);
|
||||
};
|
||||
|
||||
@@ -348,7 +311,7 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
||||
qmlInfo.append("module ");
|
||||
qmlInfo.append(m_importPath.split('/').last());
|
||||
qmlInfo.append(".");
|
||||
qmlInfo.append(assetName);
|
||||
qmlInfo.append(pd.assetName);
|
||||
qmlInfo.append('\n');
|
||||
while (qmlIt.hasNext()) {
|
||||
qmlIt.next();
|
||||
@@ -382,7 +345,7 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
||||
out << "canBeDroppedInView3D: true" << Qt::endl;
|
||||
file.close();
|
||||
}
|
||||
if (generateComponentIcon(24, iconFileName, qmlIt.filePath())) {
|
||||
if (startIconProcess(24, iconFileName, qmlIt.filePath())) {
|
||||
// Since icon is generated by external process, the file won't be
|
||||
// ready for asset gathering below, so assume its generation succeeds
|
||||
// and add it now.
|
||||
@@ -395,7 +358,7 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
||||
qmldirFile.write(qmlInfo.toUtf8());
|
||||
qmldirFile.commit();
|
||||
} else {
|
||||
addError(tr("Failed to create qmldir file for asset: \"%1\"").arg(assetName));
|
||||
addError(tr("Failed to create qmldir file for asset: \"%1\"").arg(pd.assetName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,19 +371,13 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
||||
}
|
||||
|
||||
// Copy the original asset into a subdirectory
|
||||
assetFiles.insert(sourceInfo.absoluteFilePath(),
|
||||
targetDirPath + QStringLiteral("/source scene/") + sourceInfo.fileName());
|
||||
assetFiles.insert(pd.sourceInfo.absoluteFilePath(),
|
||||
pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName());
|
||||
m_importFiles.insert(assetFiles);
|
||||
|
||||
#else
|
||||
Q_UNUSED(file)
|
||||
Q_UNUSED(options)
|
||||
#endif
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::copyImportedFiles()
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
if (!m_overwrittenImports.isEmpty()) {
|
||||
const QString progressTitle = tr("Removing old overwritten assets.");
|
||||
addInfo(progressTitle);
|
||||
@@ -461,15 +418,20 @@ void ItemLibraryAssetImporter::copyImportedFiles()
|
||||
}
|
||||
notifyProgress(100, progressTitle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::notifyProgress(int value, const QString &text) const
|
||||
void ItemLibraryAssetImporter::notifyProgress(int value, const QString &text)
|
||||
{
|
||||
emit progressChanged(value, text);
|
||||
m_progressTitle = text;
|
||||
emit progressChanged(value, m_progressTitle);
|
||||
keepUiAlive();
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::notifyProgress(int value)
|
||||
{
|
||||
notifyProgress(value, m_progressTitle);
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::keepUiAlive() const
|
||||
{
|
||||
QApplication::processEvents();
|
||||
@@ -484,7 +446,41 @@ bool ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName)
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetImporter::generateComponentIcon(int size, const QString &iconFile,
|
||||
bool ItemLibraryAssetImporter::startImportProcess(const ParseData &pd)
|
||||
{
|
||||
auto doc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
Model *model = doc ? doc->currentModel() : nullptr;
|
||||
|
||||
if (model) {
|
||||
PuppetCreator puppetCreator(doc->currentTarget(), model);
|
||||
puppetCreator.createQml2PuppetExecutableIfMissing();
|
||||
QStringList puppetArgs;
|
||||
QJsonDocument optDoc(pd.options);
|
||||
|
||||
puppetArgs << "--import3dAsset" << pd.sourceInfo.absoluteFilePath()
|
||||
<< pd.outDir.absolutePath() << QString::number(pd.importId)
|
||||
<< QString::fromUtf8(optDoc.toJson());
|
||||
|
||||
QProcessUniquePointer process = puppetCreator.createPuppetProcess(
|
||||
"custom",
|
||||
{},
|
||||
std::function<void()>(),
|
||||
[&](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
importProcessFinished(exitCode, exitStatus);
|
||||
},
|
||||
puppetArgs);
|
||||
|
||||
if (process->waitForStarted(5000)) {
|
||||
m_qmlPuppetProcesses.push_back(std::move(process));
|
||||
return true;
|
||||
} else {
|
||||
process.reset();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetImporter::startIconProcess(int size, const QString &iconFile,
|
||||
const QString &iconSource)
|
||||
{
|
||||
auto doc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
@@ -500,7 +496,7 @@ bool ItemLibraryAssetImporter::generateComponentIcon(int size, const QString &ic
|
||||
{},
|
||||
std::function<void()>(),
|
||||
[&](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
processFinished(exitCode, exitStatus);
|
||||
iconProcessFinished(exitCode, exitStatus);
|
||||
},
|
||||
puppetArgs);
|
||||
|
||||
@@ -514,9 +510,30 @@ bool ItemLibraryAssetImporter::generateComponentIcon(int size, const QString &ic
|
||||
return false;
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::postImport()
|
||||
{
|
||||
Q_ASSERT(m_qmlPuppetProcesses.empty());
|
||||
|
||||
if (!isCancelled()) {
|
||||
for (const auto &pd : qAsConst(m_parseData))
|
||||
postParseQuick3DAsset(pd);
|
||||
}
|
||||
|
||||
if (!isCancelled()) {
|
||||
// Wait for icon generation processes to finish
|
||||
if (m_qmlPuppetProcesses.empty()) {
|
||||
finalizeQuick3DImport();
|
||||
} else {
|
||||
m_qmlPuppetCount = static_cast<int>(m_qmlPuppetProcesses.size());
|
||||
const QString progressTitle = tr("Generating icons.");
|
||||
addInfo(progressTitle);
|
||||
notifyProgress(0, progressTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
||||
{
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
if (!isCancelled()) {
|
||||
// Don't allow cancel anymore as existing asset overwrites are not trivially recoverable.
|
||||
// Also, on Windows at least you can't delete a subdirectory of a watched directory,
|
||||
@@ -562,7 +579,6 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
||||
notifyFinished();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetImporter::isCancelled() const
|
||||
|
||||
@@ -29,11 +29,13 @@
|
||||
#include <qprocessuniqueptr.h>
|
||||
|
||||
#include <QSet>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qjsonobject.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qprocess.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QHash>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QStringList>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSSGAssetImportManager;
|
||||
@@ -62,11 +64,6 @@ public:
|
||||
void addWarning(const QString &warningMsg, const QString &srcPath = {}) const;
|
||||
void addInfo(const QString &infoMsg, const QString &srcPath = {}) const;
|
||||
|
||||
bool isQuick3DAsset(const QString &fileName) const;
|
||||
QVariantMap supportedOptions(const QString &modelFile) const;
|
||||
QHash<QString, QVariantMap> allOptions() const;
|
||||
QHash<QString, QStringList> supportedExtensions() const;
|
||||
|
||||
signals:
|
||||
void errorReported(const QString &, const QString &) const;
|
||||
void warningReported(const QString &, const QString &) const;
|
||||
@@ -76,32 +73,49 @@ signals:
|
||||
void importFinished();
|
||||
|
||||
private slots:
|
||||
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void iconProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
||||
private:
|
||||
struct ParseData {
|
||||
QJsonObject options;
|
||||
QDir targetDir;
|
||||
QDir outDir;
|
||||
QString targetDirPath;
|
||||
QFileInfo sourceInfo;
|
||||
QString assetName;
|
||||
QString originalAssetName;
|
||||
int importId;
|
||||
};
|
||||
|
||||
void notifyFinished();
|
||||
void reset();
|
||||
void parseFiles(const QStringList &filePaths, const QVector<QJsonObject> &options,
|
||||
const QHash<QString, int> &extToImportOptionsMap);
|
||||
void parseQuick3DAsset(const QString &file, const QVariantMap &options);
|
||||
bool preParseQuick3DAsset(const QString &file, ParseData &pd);
|
||||
void postParseQuick3DAsset(const ParseData &pd);
|
||||
void copyImportedFiles();
|
||||
|
||||
void notifyProgress(int value, const QString &text) const;
|
||||
void notifyProgress(int value, const QString &text);
|
||||
void notifyProgress(int value);
|
||||
void keepUiAlive() const;
|
||||
bool confirmAssetOverwrite(const QString &assetName);
|
||||
bool generateComponentIcon(int size, const QString &iconFile, const QString &iconSource);
|
||||
bool startImportProcess(const ParseData &pd);
|
||||
bool startIconProcess(int size, const QString &iconFile, const QString &iconSource);
|
||||
void postImport();
|
||||
void finalizeQuick3DImport();
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
QScopedPointer<QSSGAssetImportManager> m_quick3DAssetImporter;
|
||||
QSet<QHash<QString, QString>> m_importFiles;
|
||||
QSet<QString> m_overwrittenImports;
|
||||
#endif
|
||||
bool m_isImporting = false;
|
||||
bool m_cancelled = false;
|
||||
QString m_importPath;
|
||||
QTemporaryDir *m_tempDir = nullptr;
|
||||
std::vector<QProcessUniquePointer> m_qmlPuppetProcesses;
|
||||
int m_qmlPuppetCount = 0;
|
||||
int m_qmlImportFinishedCount = 0;
|
||||
int m_importIdCounter = 1000000; // Use ids in range unlikely to clash with any normal process exit codes
|
||||
QHash<int, ParseData> m_parseData;
|
||||
QString m_progressTitle;
|
||||
};
|
||||
} // QmlDesigner
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "itemlibraryview.h"
|
||||
#include "itemlibrarywidget.h"
|
||||
#include "itemlibraryassetimportdialog.h"
|
||||
#include "metainfo.h"
|
||||
#include <asynchronousimagecache.h>
|
||||
#include <bindingproperty.h>
|
||||
@@ -216,4 +217,46 @@ void ItemLibraryView::updateImports()
|
||||
m_widget->delayedUpdateModel();
|
||||
}
|
||||
|
||||
void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap)
|
||||
{
|
||||
QVariantMap extMap = qvariant_cast<QVariantMap>(supportMap.value("extensions"));
|
||||
if (m_importableExtensions3DMap != extMap) {
|
||||
DesignerActionManager *actionManager =
|
||||
&QmlDesignerPlugin::instance()->viewManager().designerActionManager();
|
||||
|
||||
// All things importable by QSSGAssetImportManager are considered to be in the same category
|
||||
// so we don't get multiple separate import dialogs when different file types are imported.
|
||||
const QString category = tr("3D Assets");
|
||||
|
||||
if (!m_importableExtensions3DMap.isEmpty())
|
||||
actionManager->unregisterAddResourceHandlers(category);
|
||||
|
||||
m_importableExtensions3DMap = extMap;
|
||||
|
||||
auto handle3DModel = [this](const QStringList &fileNames, const QString &defaultDir) -> bool {
|
||||
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
|
||||
m_importableExtensions3DMap,
|
||||
m_importOptions3DMap,
|
||||
Core::ICore::mainWindow());
|
||||
importDlg->show();
|
||||
return true;
|
||||
};
|
||||
|
||||
auto add3DHandler = [&](const QString &category, const QString &ext) {
|
||||
const QString filter = QStringLiteral("*.%1").arg(ext);
|
||||
actionManager->registerAddResourceHandler(
|
||||
AddResourceHandler(category, filter, handle3DModel, 10));
|
||||
};
|
||||
|
||||
const auto groups = extMap.keys();
|
||||
for (const auto &group : groups) {
|
||||
const QStringList exts = extMap[group].toStringList();
|
||||
for (const auto &ext : exts)
|
||||
add3DHandler(category, ext);
|
||||
}
|
||||
}
|
||||
|
||||
m_importOptions3DMap = qvariant_cast<QVariantMap>(supportMap.value("options"));
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
void modelAboutToBeDetached(Model *model) override;
|
||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||
void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override;
|
||||
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
||||
|
||||
void setResourcePath(const QString &resourcePath);
|
||||
|
||||
@@ -66,6 +67,8 @@ private:
|
||||
QPointer<ItemLibraryWidget> m_widget;
|
||||
ImportManagerView *m_importManagerView;
|
||||
bool m_hasErrors = false;
|
||||
QVariantMap m_importableExtensions3DMap;
|
||||
QVariantMap m_importOptions3DMap;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "itemlibrarywidget.h"
|
||||
|
||||
#include "customfilesystemmodel.h"
|
||||
#include "itemlibraryassetimportdialog.h"
|
||||
#include "itemlibraryiconimageprovider.h"
|
||||
|
||||
#include <theme.h>
|
||||
@@ -53,10 +52,6 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDrag>
|
||||
#include <QFileDialog>
|
||||
@@ -205,49 +200,6 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
addResources({});
|
||||
});
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
DesignerActionManager *actionManager =
|
||||
&QmlDesignerPlugin::instance()->viewManager().designerActionManager();
|
||||
|
||||
auto handle3DModel = [](const QStringList &fileNames, const QString &defaultDir) -> bool {
|
||||
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir, Core::ICore::mainWindow());
|
||||
importDlg->show();
|
||||
return true;
|
||||
};
|
||||
|
||||
auto add3DHandler = [&](const QString &category, const QString &ext) {
|
||||
const QString filter = QStringLiteral("*.%1").arg(ext);
|
||||
actionManager->registerAddResourceHandler(
|
||||
AddResourceHandler(category, filter, handle3DModel, 10));
|
||||
};
|
||||
|
||||
QSSGAssetImportManager importManager;
|
||||
QHash<QString, QStringList> supportedExtensions = importManager.getSupportedExtensions();
|
||||
|
||||
// All things importable by QSSGAssetImportManager are considered to be in the same category
|
||||
// so we don't get multiple separate import dialogs when different file types are imported.
|
||||
const QString category = tr("3D Assets");
|
||||
|
||||
// Skip if 3D asset handlers have already been added
|
||||
const QList<AddResourceHandler> handlers = actionManager->addResourceHandler();
|
||||
bool categoryAlreadyAdded = false;
|
||||
for (const auto &handler : handlers) {
|
||||
if (handler.category == category) {
|
||||
categoryAlreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!categoryAlreadyAdded) {
|
||||
const auto groups = supportedExtensions.keys();
|
||||
for (const auto &group : groups) {
|
||||
const auto extensions = supportedExtensions[group];
|
||||
for (const auto &ext : extensions)
|
||||
add3DHandler(category, ext);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const auto dropSupport = new Utils::DropSupport(
|
||||
m_resourcesView.data(), [this](QDropEvent *event, Utils::DropSupport *) {
|
||||
// Accept supported file types
|
||||
|
||||
@@ -189,6 +189,7 @@ public:
|
||||
void emitRenderImage3DChanged(const QImage &image);
|
||||
void emitUpdateActiveScene3D(const QVariantMap &sceneState);
|
||||
void emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||
void emitImport3DSupportChanged(const QVariantMap &supportMap);
|
||||
|
||||
void sendTokenToInstances(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
||||
|
||||
@@ -248,6 +249,7 @@ public:
|
||||
|
||||
virtual void renderImage3DChanged(const QImage &image);
|
||||
virtual void updateActiveScene3D(const QVariantMap &sceneState);
|
||||
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
||||
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||
|
||||
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
||||
|
||||
@@ -1578,6 +1578,9 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
|
||||
updatePreviewImageForNode(node, image);
|
||||
}
|
||||
}
|
||||
} else if (command.type() == PuppetToCreatorCommand::Import3DSupport) {
|
||||
const QVariantMap supportMap = qvariant_cast<QVariantMap>(command.data());
|
||||
emitImport3DSupportChanged(supportMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,6 +386,10 @@ void AbstractView::updateActiveScene3D(const QVariantMap & /*sceneState*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractView::updateImport3DSupport(const QVariantMap & /*supportMap*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, const QPixmap & /*pixmap*/)
|
||||
{
|
||||
}
|
||||
@@ -804,6 +808,12 @@ void AbstractView::emitModelNodelPreviewPixmapChanged(const ModelNode &node, con
|
||||
model()->d->notifyModelNodePreviewPixmapChanged(node, pixmap);
|
||||
}
|
||||
|
||||
void AbstractView::emitImport3DSupportChanged(const QVariantMap &supportMap)
|
||||
{
|
||||
if (model())
|
||||
model()->d->notifyImport3DSupportChanged(supportMap);
|
||||
}
|
||||
|
||||
void AbstractView::emitRewriterEndTransaction()
|
||||
{
|
||||
if (model())
|
||||
|
||||
@@ -575,6 +575,11 @@ void ModelPrivate::notifyModelNodePreviewPixmapChanged(const ModelNode &node, co
|
||||
[&](AbstractView *view) { view->modelNodePreviewPixmapChanged(node, pixmap); });
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyImport3DSupportChanged(const QVariantMap &supportMap)
|
||||
{
|
||||
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyRewriterBeginTransaction()
|
||||
{
|
||||
notifyNodeInstanceViewLast([&](AbstractView *view) { view->rewriterBeginTransaction(); });
|
||||
|
||||
@@ -176,6 +176,7 @@ public:
|
||||
void notifyRenderImage3DChanged(const QImage &image);
|
||||
void notifyUpdateActiveScene3D(const QVariantMap &sceneState);
|
||||
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
||||
|
||||
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
||||
|
||||
|
||||
@@ -137,6 +137,14 @@ extend_qtc_executable(qml2puppet
|
||||
icongizmoimageprovider.cpp icongizmoimageprovider.h
|
||||
)
|
||||
|
||||
find_package(Qt5 5.15.0 COMPONENTS Quick3DAssetImport QUIET)
|
||||
extend_qtc_executable(qml2puppet
|
||||
CONDITION TARGET Qt5::Quick3DAssetImport
|
||||
FEATURE_INFO "Qt Quick 3D asset import"
|
||||
DEPENDS Qt5::Quick3DAssetImportPrivate
|
||||
DEFINES IMPORT_QUICK3D_ASSETS
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.0.0
|
||||
|
||||
@@ -151,6 +159,12 @@ extend_qtc_executable(qml2puppet
|
||||
iconrenderer.cpp iconrenderer.h
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
SOURCES_PREFIX "${SRCDIR}/qml2puppet/import3d"
|
||||
SOURCES
|
||||
import3d.cpp import3d.h
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
SOURCES_PREFIX "${SRCDIR}/qml2puppet/instances"
|
||||
SOURCES
|
||||
|
||||
@@ -243,6 +243,8 @@ QtcTool {
|
||||
"editor3d/icongizmoimageprovider.h",
|
||||
"iconrenderer/iconrenderer.cpp",
|
||||
"iconrenderer/iconrenderer.h",
|
||||
"import3d/import3d.cpp",
|
||||
"import3d/import3d.h",
|
||||
"qml2puppetmain.cpp",
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user