forked from qt-creator/qt-creator
Show 3D import preview
Show preview of 3D import in item library import dialog when importing a single 3D asset. Fixes: QDS-11111 Change-Id: I13135be1e931cbee034ca8a89654c0827b937bdf Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
@@ -18,6 +18,7 @@ public:
|
|||||||
ActiveSceneChanged,
|
ActiveSceneChanged,
|
||||||
ActiveSplitChanged,
|
ActiveSplitChanged,
|
||||||
RenderModelNodePreviewImage,
|
RenderModelNodePreviewImage,
|
||||||
|
Import3DPreviewImage,
|
||||||
Import3DSupport,
|
Import3DSupport,
|
||||||
NodeAtPos,
|
NodeAtPos,
|
||||||
BakeLightsProgress,
|
BakeLightsProgress,
|
||||||
|
@@ -55,7 +55,8 @@ enum class View3DActionType {
|
|||||||
EditCameraRotation,
|
EditCameraRotation,
|
||||||
EditCameraMove,
|
EditCameraMove,
|
||||||
EditCameraStopAllMoves,
|
EditCameraStopAllMoves,
|
||||||
SetLastSceneEnvData
|
SetLastSceneEnvData,
|
||||||
|
Import3dUpdatePreviewImage
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool isNanotraceEnabled()
|
constexpr bool isNanotraceEnabled()
|
||||||
|
@@ -741,6 +741,8 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h
|
assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h
|
||||||
assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h
|
assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h
|
||||||
assetimportupdatetreeview.cpp assetimportupdatetreeview.h
|
assetimportupdatetreeview.cpp assetimportupdatetreeview.h
|
||||||
|
import3dcanvas.cpp import3dcanvas.h
|
||||||
|
import3dconnectionmanager.cpp import3dconnectionmanager.h
|
||||||
itemlibrary.qrc
|
itemlibrary.qrc
|
||||||
itemlibraryconstants.h
|
itemlibraryconstants.h
|
||||||
itemlibraryimageprovider.cpp itemlibraryimageprovider.h
|
itemlibraryimageprovider.cpp itemlibraryimageprovider.h
|
||||||
|
@@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "import3dcanvas.h"
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QLinearGradient>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static QImage createGradientImage(int width, int height) {
|
||||||
|
QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
|
||||||
|
QLinearGradient gradient(0, 0, 0, height);
|
||||||
|
gradient.setColorAt(0, QColor(0x999999));
|
||||||
|
gradient.setColorAt(1, QColor(0x222222));
|
||||||
|
|
||||||
|
QPainter painter(&image);
|
||||||
|
painter.fillRect(0, 0, width, height, gradient);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
Import3dCanvas::Import3dCanvas(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Import3dCanvas::updateRenderImage(const QImage &img)
|
||||||
|
{
|
||||||
|
m_image = img;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Import3dCanvas::paintEvent([[maybe_unused]] QPaintEvent *e)
|
||||||
|
{
|
||||||
|
QWidget::paintEvent(e);
|
||||||
|
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
if (m_image.isNull()) {
|
||||||
|
QImage image = createGradientImage(width(), height());
|
||||||
|
painter.drawImage(rect(), image, QRect(0, 0, image.width(), image.height()));
|
||||||
|
} else {
|
||||||
|
painter.drawImage(rect(), m_image, QRect(0, 0, m_image.width(), m_image.height()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Import3dCanvas::resizeEvent(QResizeEvent *)
|
||||||
|
{
|
||||||
|
emit requestImageUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class Import3dCanvas : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Import3dCanvas(QWidget *parent);
|
||||||
|
|
||||||
|
void updateRenderImage(const QImage &img);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void requestImageUpdate();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage m_image;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "import3dconnectionmanager.h"
|
||||||
|
|
||||||
|
#include <imagecontainer.h>
|
||||||
|
#include <puppettocreatorcommand.h>
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
Import3dConnectionManager::Import3dConnectionManager()
|
||||||
|
{
|
||||||
|
connections().clear(); // Remove default interactive puppets
|
||||||
|
connections().emplace_back("Import 3D", "import3dmode");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Import3dConnectionManager::setPreviewImageCallback(ImageCallback callback)
|
||||||
|
{
|
||||||
|
m_previewImageCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Import3dConnectionManager::dispatchCommand(const QVariant &command,
|
||||||
|
ConnectionManagerInterface::Connection &connection)
|
||||||
|
{
|
||||||
|
static const int commandType = QMetaType::type("PuppetToCreatorCommand");
|
||||||
|
|
||||||
|
if (command.typeId() == commandType) {
|
||||||
|
auto cmd = command.value<PuppetToCreatorCommand>();
|
||||||
|
switch (cmd.type()) {
|
||||||
|
case PuppetToCreatorCommand::Import3DPreviewImage: {
|
||||||
|
ImageContainer container = qvariant_cast<ImageContainer>(cmd.data());
|
||||||
|
QImage image = container.image();
|
||||||
|
if (!image.isNull())
|
||||||
|
m_previewImageCallback(image);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
InteractiveConnectionManager::dispatchCommand(command, connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "interactiveconnectionmanager.h"
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QImage)
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class Import3dConnectionManager : public InteractiveConnectionManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using ImageCallback = std::function<void(const QImage &)>;
|
||||||
|
|
||||||
|
Import3dConnectionManager();
|
||||||
|
|
||||||
|
void setPreviewImageCallback(ImageCallback callback);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dispatchCommand(const QVariant &command, Connection &connection) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageCallback m_previewImageCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -4,15 +4,19 @@
|
|||||||
#include "itemlibraryassetimportdialog.h"
|
#include "itemlibraryassetimportdialog.h"
|
||||||
#include "ui_itemlibraryassetimportdialog.h"
|
#include "ui_itemlibraryassetimportdialog.h"
|
||||||
|
|
||||||
|
#include "import3dcanvas.h"
|
||||||
|
#include "import3dconnectionmanager.h"
|
||||||
|
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <model/modelutils.h>
|
#include <model/modelutils.h>
|
||||||
|
#include <nodeinstanceview.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <rewriterview.h>
|
||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
|
|
||||||
#include <theme.h>
|
#include <theme.h>
|
||||||
#include <utils/filepath.h>
|
|
||||||
#include <utils/outputformatter.h>
|
#include <utils/outputformatter.h>
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
@@ -74,9 +78,10 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
|||||||
const QStringList &importFiles, const QString &defaulTargetDirectory,
|
const QStringList &importFiles, const QString &defaulTargetDirectory,
|
||||||
const QVariantMap &supportedExts, const QVariantMap &supportedOpts,
|
const QVariantMap &supportedExts, const QVariantMap &supportedOpts,
|
||||||
const QJsonObject &defaultOpts, const QSet<QString> &preselectedFilesForOverwrite,
|
const QJsonObject &defaultOpts, const QSet<QString> &preselectedFilesForOverwrite,
|
||||||
QWidget *parent)
|
AbstractView *view, QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, ui(new Ui::ItemLibraryAssetImportDialog)
|
, ui(new Ui::ItemLibraryAssetImportDialog)
|
||||||
|
, m_view(view)
|
||||||
, m_importer(this)
|
, m_importer(this)
|
||||||
, m_preselectedFilesForOverwrite(preselectedFilesForOverwrite)
|
, m_preselectedFilesForOverwrite(preselectedFilesForOverwrite)
|
||||||
{
|
{
|
||||||
@@ -107,11 +112,9 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
|||||||
if (m_quick3DFiles.size() != importFiles.size())
|
if (m_quick3DFiles.size() != importFiles.size())
|
||||||
addWarning("Cannot import 3D and other assets simultaneously. Skipping non-3D assets.");
|
addWarning("Cannot import 3D and other assets simultaneously. Skipping non-3D assets.");
|
||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Import"));
|
connect(ui->importButton, &QPushButton::clicked, this, &ItemLibraryAssetImportDialog::onImport);
|
||||||
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked,
|
|
||||||
this, &ItemLibraryAssetImportDialog::onImport);
|
|
||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
ui->importButton->setDefault(true);
|
||||||
|
|
||||||
ui->advancedSettingsButton->setStyleSheet(
|
ui->advancedSettingsButton->setStyleSheet(
|
||||||
"QPushButton#advancedSettingsButton {background-color: transparent}");
|
"QPushButton#advancedSettingsButton {background-color: transparent}");
|
||||||
@@ -210,10 +213,14 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
|||||||
ui->tabWidget->setCurrentIndex(0);
|
ui->tabWidget->setCurrentIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked,
|
connect(ui->closeButton, &QPushButton::clicked,
|
||||||
this, &ItemLibraryAssetImportDialog::onClose);
|
this, &ItemLibraryAssetImportDialog::onClose);
|
||||||
|
connect(ui->acceptButton, &QPushButton::clicked,
|
||||||
|
this, &ItemLibraryAssetImportDialog::onAccept);
|
||||||
connect(ui->tabWidget, &QTabWidget::currentChanged,
|
connect(ui->tabWidget, &QTabWidget::currentChanged,
|
||||||
this, &ItemLibraryAssetImportDialog::updateUi);
|
this, &ItemLibraryAssetImportDialog::updateUi);
|
||||||
|
connect(canvas(), &Import3dCanvas::requestImageUpdate,
|
||||||
|
this, &ItemLibraryAssetImportDialog::onRequestImageUpdate);
|
||||||
|
|
||||||
connect(&m_importer, &ItemLibraryAssetImporter::errorReported,
|
connect(&m_importer, &ItemLibraryAssetImporter::errorReported,
|
||||||
this, &ItemLibraryAssetImportDialog::addError);
|
this, &ItemLibraryAssetImportDialog::addError);
|
||||||
@@ -227,6 +234,8 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
|||||||
this, &ItemLibraryAssetImportDialog::onImportFinished);
|
this, &ItemLibraryAssetImportDialog::onImportFinished);
|
||||||
connect(&m_importer, &ItemLibraryAssetImporter::progressChanged,
|
connect(&m_importer, &ItemLibraryAssetImporter::progressChanged,
|
||||||
this, &ItemLibraryAssetImportDialog::setImportProgress);
|
this, &ItemLibraryAssetImportDialog::setImportProgress);
|
||||||
|
connect(&m_importer, &ItemLibraryAssetImporter::importReadyForPreview,
|
||||||
|
this, &ItemLibraryAssetImportDialog::onImportReadyForPreview);
|
||||||
|
|
||||||
addInfo(tr("Select import options and press \"Import\" to import the following files:"));
|
addInfo(tr("Select import options and press \"Import\" to import the following files:"));
|
||||||
for (const auto &file : std::as_const(m_quick3DFiles))
|
for (const auto &file : std::as_const(m_quick3DFiles))
|
||||||
@@ -240,10 +249,12 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
|||||||
|
|
||||||
ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog()
|
ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog()
|
||||||
{
|
{
|
||||||
|
cleanupPreviewPuppet();
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::updateImport(const ModelNode &updateNode,
|
void ItemLibraryAssetImportDialog::updateImport(AbstractView *view,
|
||||||
|
const ModelNode &updateNode,
|
||||||
const QVariantMap &supportedExts,
|
const QVariantMap &supportedExts,
|
||||||
const QVariantMap &supportedOpts)
|
const QVariantMap &supportedOpts)
|
||||||
{
|
{
|
||||||
@@ -332,7 +343,8 @@ void ItemLibraryAssetImportDialog::updateImport(const ModelNode &updateNode,
|
|||||||
{sourceInfo.absoluteFilePath()},
|
{sourceInfo.absoluteFilePath()},
|
||||||
node.model()->fileUrl().toLocalFile(),
|
node.model()->fileUrl().toLocalFile(),
|
||||||
supportedExts, supportedOpts, options,
|
supportedExts, supportedOpts, options,
|
||||||
preselectedFiles, Core::ICore::dialogParent());
|
preselectedFiles, view,
|
||||||
|
Core::ICore::dialogParent());
|
||||||
importDlg->show();
|
importDlg->show();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -829,6 +841,140 @@ bool ItemLibraryAssetImportDialog::isHiddenOption(const QString &id)
|
|||||||
return hiddenOptions.contains(id);
|
return hiddenOptions.contains(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAssetImportDialog::startPreview()
|
||||||
|
{
|
||||||
|
cleanupPreviewPuppet();
|
||||||
|
|
||||||
|
// Preview is done via custom QML file added into the temporary folder of the preview
|
||||||
|
QString previewQml =
|
||||||
|
R"(
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick3D
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
width: %1
|
||||||
|
height: %2
|
||||||
|
|
||||||
|
property string sceneModelName: "%3"
|
||||||
|
property alias view3d: view3d
|
||||||
|
property string extents
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 1.0; color: "#222222" }
|
||||||
|
GradientStop { position: 0.0; color: "#999999" }
|
||||||
|
}
|
||||||
|
|
||||||
|
View3D {
|
||||||
|
id: view3d
|
||||||
|
anchors.fill: parent
|
||||||
|
camera: viewCamera
|
||||||
|
|
||||||
|
environment: SceneEnvironment {
|
||||||
|
antialiasingMode: SceneEnvironment.MSAA
|
||||||
|
antialiasingQuality: SceneEnvironment.VeryHigh
|
||||||
|
}
|
||||||
|
|
||||||
|
PerspectiveCamera {
|
||||||
|
id: viewCamera
|
||||||
|
z: 600
|
||||||
|
y: 600
|
||||||
|
x: 600
|
||||||
|
eulerRotation.x: -45
|
||||||
|
eulerRotation.y: -45
|
||||||
|
clipFar: 100000
|
||||||
|
clipNear: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectionalLight {
|
||||||
|
rotation: viewCamera.rotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
color: "white"
|
||||||
|
text: root.extents
|
||||||
|
font.pixelSize: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
QSize size = canvas()->size();
|
||||||
|
previewQml = previewQml.arg(size.width()).arg(size.height()).arg(m_previewCompName);
|
||||||
|
|
||||||
|
m_previewFile.writeFileContents(previewQml.toUtf8());
|
||||||
|
|
||||||
|
if (!m_previewFile.exists()) {
|
||||||
|
addWarning("Failed to write preview file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_connectionManager = new Import3dConnectionManager;
|
||||||
|
m_rewriterView = new RewriterView{m_view->externalDependencies(), RewriterView::Amend};
|
||||||
|
m_nodeInstanceView = new NodeInstanceView{*m_connectionManager, m_view->externalDependencies()};
|
||||||
|
|
||||||
|
#ifdef QDS_USE_PROJECTSTORAGE
|
||||||
|
m_model = m_view->model()->createModel("Item");
|
||||||
|
#else
|
||||||
|
m_model = QmlDesigner::Model::create("QtQuick/Item", 2, 1);
|
||||||
|
m_model->setFileUrl(m_previewFile.toUrl());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto textDocument = std::make_unique<QTextDocument>(previewQml);
|
||||||
|
auto modifier = std::make_unique<NotIndentingTextEditModifier>(textDocument.get(),
|
||||||
|
QTextCursor{textDocument.get()});
|
||||||
|
m_rewriterView->setTextModifier(modifier.get());
|
||||||
|
m_model->setRewriterView(m_rewriterView);
|
||||||
|
|
||||||
|
if (!m_rewriterView->errors().isEmpty()) {
|
||||||
|
addWarning("Preview scene creation failed.");
|
||||||
|
cleanupPreviewPuppet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nodeInstanceView->setTarget(m_view->nodeInstanceView()->target());
|
||||||
|
|
||||||
|
auto previewImageCallback = [this](const QImage &image) {
|
||||||
|
canvas()->updateRenderImage(image);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto crashCallback = [&] {
|
||||||
|
addWarning("Preview process crashed.");
|
||||||
|
cleanupPreviewPuppet();
|
||||||
|
};
|
||||||
|
|
||||||
|
m_connectionManager->setPreviewImageCallback(std::move(previewImageCallback));
|
||||||
|
m_nodeInstanceView->setCrashCallback(std::move(crashCallback));
|
||||||
|
|
||||||
|
m_model->setNodeInstanceView(m_nodeInstanceView);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAssetImportDialog::cleanupPreviewPuppet()
|
||||||
|
{
|
||||||
|
if (m_model) {
|
||||||
|
m_model->setNodeInstanceView({});
|
||||||
|
m_model->setRewriterView({});
|
||||||
|
m_model.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nodeInstanceView)
|
||||||
|
m_nodeInstanceView->setCrashCallback({});
|
||||||
|
|
||||||
|
if (m_connectionManager)
|
||||||
|
m_connectionManager->setPreviewImageCallback({});
|
||||||
|
|
||||||
|
delete m_rewriterView;
|
||||||
|
delete m_nodeInstanceView;
|
||||||
|
delete m_connectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
Import3dCanvas *ItemLibraryAssetImportDialog::canvas()
|
||||||
|
{
|
||||||
|
return ui->import3dcanvas;
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event)
|
void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event)
|
||||||
{
|
{
|
||||||
m_dialogHeight = event->size().height();
|
m_dialogHeight = event->size().height();
|
||||||
@@ -837,8 +983,8 @@ void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event)
|
|||||||
|
|
||||||
void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing)
|
void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing)
|
||||||
{
|
{
|
||||||
ui->buttonBox->button(QDialogButtonBox::Close)->setEnabled(true);
|
ui->closeButton->setEnabled(true);
|
||||||
ui->buttonBox->button(QDialogButtonBox::Close)->setText(importing ? tr("Cancel") : tr("Close"));
|
ui->closeButton->setText(importing ? tr("Cancel") : tr("Close"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::addError(const QString &error, const QString &srcPath)
|
void ItemLibraryAssetImportDialog::addError(const QString &error, const QString &srcPath)
|
||||||
@@ -860,16 +1006,21 @@ void ItemLibraryAssetImportDialog::addInfo(const QString &info, const QString &s
|
|||||||
|
|
||||||
void ItemLibraryAssetImportDialog::onImport()
|
void ItemLibraryAssetImportDialog::onImport()
|
||||||
{
|
{
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
ui->acceptButton->setEnabled(false);
|
||||||
|
ui->importButton->setEnabled(false);
|
||||||
setCloseButtonState(true);
|
setCloseButtonState(true);
|
||||||
ui->progressBar->setValue(0);
|
ui->progressBar->setValue(0);
|
||||||
|
|
||||||
if (!m_quick3DFiles.isEmpty()) {
|
if (!m_quick3DFiles.isEmpty()) {
|
||||||
|
if (!m_previewCompName.isEmpty()) {
|
||||||
|
m_importer.reImportQuick3D(m_previewCompName, m_importOptions);
|
||||||
|
} else {
|
||||||
m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath,
|
m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath,
|
||||||
m_importOptions, m_extToImportOptionsMap,
|
m_importOptions, m_extToImportOptionsMap,
|
||||||
m_preselectedFilesForOverwrite);
|
m_preselectedFilesForOverwrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::setImportProgress(int value, const QString &text)
|
void ItemLibraryAssetImportDialog::setImportProgress(int value, const QString &text)
|
||||||
{
|
{
|
||||||
@@ -881,10 +1032,28 @@ void ItemLibraryAssetImportDialog::setImportProgress(int value, const QString &t
|
|||||||
ui->progressBar->setValue(value);
|
ui->progressBar->setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAssetImportDialog::onImportReadyForPreview(const QString &path, const QString &compName)
|
||||||
|
{
|
||||||
|
m_previewFile = Utils::FilePath::fromString(path).pathAppended(m_importer.previewFileName());
|
||||||
|
m_previewCompName = compName;
|
||||||
|
QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::startPreview);
|
||||||
|
|
||||||
|
ui->acceptButton->setEnabled(true);
|
||||||
|
ui->importButton->setEnabled(true);
|
||||||
|
|
||||||
|
addInfo(tr("Generating import preview for %1.").arg(compName));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAssetImportDialog::onRequestImageUpdate()
|
||||||
|
{
|
||||||
|
if (m_nodeInstanceView)
|
||||||
|
m_nodeInstanceView->view3DAction(View3DActionType::Import3dUpdatePreviewImage, canvas()->size());
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::onImportNearlyFinished()
|
void ItemLibraryAssetImportDialog::onImportNearlyFinished()
|
||||||
{
|
{
|
||||||
// Canceling import is no longer doable
|
// Canceling import is no longer doable
|
||||||
ui->buttonBox->button(QDialogButtonBox::Close)->setEnabled(false);
|
ui->closeButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::onImportFinished()
|
void ItemLibraryAssetImportDialog::onImportFinished()
|
||||||
@@ -920,6 +1089,16 @@ void ItemLibraryAssetImportDialog::onClose()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAssetImportDialog::onAccept()
|
||||||
|
{
|
||||||
|
cleanupPreviewPuppet();
|
||||||
|
|
||||||
|
ui->importButton->setEnabled(false);
|
||||||
|
ui->acceptButton->setEnabled(false);
|
||||||
|
|
||||||
|
m_importer.finalizeQuick3DImport();
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImportDialog::toggleAdvanced()
|
void ItemLibraryAssetImportDialog::toggleAdvanced()
|
||||||
{
|
{
|
||||||
m_advancedMode = !m_advancedMode;
|
m_advancedMode = !m_advancedMode;
|
||||||
|
@@ -3,14 +3,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "itemlibraryassetimporter.h"
|
#include "itemlibraryassetimporter.h"
|
||||||
#include "modelnode.h"
|
|
||||||
|
#include <modelnode.h>
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QPointer>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QGridLayout;
|
class QGridLayout;
|
||||||
|
class QPushButton;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -19,6 +24,10 @@ class OutputFormatter;
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
class ItemLibraryAssetImporter;
|
class ItemLibraryAssetImporter;
|
||||||
|
class Import3dCanvas;
|
||||||
|
class Import3dConnectionManager;
|
||||||
|
class NodeInstanceView;
|
||||||
|
class RewriterView;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ItemLibraryAssetImportDialog;
|
class ItemLibraryAssetImportDialog;
|
||||||
@@ -35,10 +44,12 @@ public:
|
|||||||
const QVariantMap &supportedOpts,
|
const QVariantMap &supportedOpts,
|
||||||
const QJsonObject &defaultOpts,
|
const QJsonObject &defaultOpts,
|
||||||
const QSet<QString> &preselectedFilesForOverwrite,
|
const QSet<QString> &preselectedFilesForOverwrite,
|
||||||
|
AbstractView *view,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
~ItemLibraryAssetImportDialog();
|
~ItemLibraryAssetImportDialog();
|
||||||
|
|
||||||
static void updateImport(const ModelNode &updateNode,
|
static void updateImport(AbstractView *view,
|
||||||
|
const ModelNode &updateNode,
|
||||||
const QVariantMap &supportedExts,
|
const QVariantMap &supportedExts,
|
||||||
const QVariantMap &supportedOpts);
|
const QVariantMap &supportedOpts);
|
||||||
|
|
||||||
@@ -55,9 +66,12 @@ private:
|
|||||||
|
|
||||||
void onImport();
|
void onImport();
|
||||||
void setImportProgress(int value, const QString &text);
|
void setImportProgress(int value, const QString &text);
|
||||||
|
void onImportReadyForPreview(const QString &path, const QString &compName);
|
||||||
|
void onRequestImageUpdate();
|
||||||
void onImportNearlyFinished();
|
void onImportNearlyFinished();
|
||||||
void onImportFinished();
|
void onImportFinished();
|
||||||
void onClose();
|
void onClose();
|
||||||
|
void onAccept();
|
||||||
void toggleAdvanced();
|
void toggleAdvanced();
|
||||||
|
|
||||||
void createTab(const QString &tabLabel, int optionsIndex, const QJsonObject &groups);
|
void createTab(const QString &tabLabel, int optionsIndex, const QJsonObject &groups);
|
||||||
@@ -69,8 +83,19 @@ private:
|
|||||||
bool isSimpleOption(const QString &id);
|
bool isSimpleOption(const QString &id);
|
||||||
bool isHiddenOption(const QString &id);
|
bool isHiddenOption(const QString &id);
|
||||||
|
|
||||||
|
void startPreview();
|
||||||
|
void cleanupPreviewPuppet();
|
||||||
|
Import3dCanvas *canvas();
|
||||||
|
|
||||||
Ui::ItemLibraryAssetImportDialog *ui = nullptr;
|
Ui::ItemLibraryAssetImportDialog *ui = nullptr;
|
||||||
Utils::OutputFormatter *m_outputFormatter = nullptr;
|
Utils::OutputFormatter *m_outputFormatter = nullptr;
|
||||||
|
QPointer<Import3dConnectionManager> m_connectionManager;
|
||||||
|
QPointer<NodeInstanceView> m_nodeInstanceView;
|
||||||
|
QPointer<RewriterView> m_rewriterView;
|
||||||
|
QPointer<AbstractView> m_view;
|
||||||
|
ModelPointer m_model;
|
||||||
|
Utils::FilePath m_previewFile;
|
||||||
|
QString m_previewCompName;
|
||||||
|
|
||||||
struct OptionsData
|
struct OptionsData
|
||||||
{
|
{
|
||||||
|
@@ -6,15 +6,15 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>630</width>
|
<width>1100</width>
|
||||||
<height>350</height>
|
<height>350</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Asset Import</string>
|
<string>Asset Import</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item row="0" column="0" colspan="2">
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
@@ -24,6 +24,12 @@
|
|||||||
<verstretch>2</verstretch>
|
<verstretch>2</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>550</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -98,6 +104,12 @@
|
|||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -111,16 +123,74 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<property name="standardButtons">
|
<item>
|
||||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="closeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="importButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Import</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="acceptButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Accept</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Import3dCanvas" name="import3dcanvas" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>300</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Import3dCanvas</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>import3dcanvas.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/async.h>
|
#include <utils/async.h>
|
||||||
|
#include <utils/filepath.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@@ -58,8 +59,6 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
|||||||
const QHash<QString, int> &extToImportOptionsMap,
|
const QHash<QString, int> &extToImportOptionsMap,
|
||||||
const QSet<QString> &preselectedFilesForOverwrite)
|
const QSet<QString> &preselectedFilesForOverwrite)
|
||||||
{
|
{
|
||||||
if (m_isImporting)
|
|
||||||
cancelImport();
|
|
||||||
reset();
|
reset();
|
||||||
m_isImporting = true;
|
m_isImporting = true;
|
||||||
|
|
||||||
@@ -92,6 +91,53 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAssetImporter::reImportQuick3D(const QString &assetName,
|
||||||
|
const QVector<QJsonObject> &options)
|
||||||
|
{
|
||||||
|
if (!assetName.isEmpty() && !m_parseData.contains(assetName)) {
|
||||||
|
addError(tr("Attempted to reimport non-existing asset: %1").arg(assetName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseData &pd = m_parseData[assetName];
|
||||||
|
// Change outDir just in case reimport generates different files
|
||||||
|
QDir oldDir = pd.outDir;
|
||||||
|
QString assetFolder = generateAssetFolderName(pd.assetName);
|
||||||
|
pd.outDir.cdUp();
|
||||||
|
pd.outDir.mkpath(assetFolder);
|
||||||
|
|
||||||
|
if (!pd.outDir.cd(assetFolder)) {
|
||||||
|
addError(tr("Could not access temporary asset directory: \"%1\".")
|
||||||
|
.arg(pd.outDir.filePath(assetFolder)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldDir.absolutePath().contains(tempDirNameBase()))
|
||||||
|
oldDir.removeRecursively();
|
||||||
|
|
||||||
|
m_isImporting = false;
|
||||||
|
m_cancelled = false;
|
||||||
|
|
||||||
|
m_puppetProcess.reset();
|
||||||
|
m_requiredImports.clear();
|
||||||
|
m_currentImportId = 0;
|
||||||
|
m_puppetQueue.clear();
|
||||||
|
|
||||||
|
for (ParseData &pd : m_parseData)
|
||||||
|
pd.importId = -1;
|
||||||
|
|
||||||
|
pd.options = options[pd.optionsIndex];
|
||||||
|
pd.importId = 1;
|
||||||
|
|
||||||
|
m_importFiles.remove(assetName);
|
||||||
|
|
||||||
|
m_importIdToAssetNameMap.clear();
|
||||||
|
m_importIdToAssetNameMap[pd.importId] = assetName;
|
||||||
|
|
||||||
|
m_puppetQueue.append(pd.importId);
|
||||||
|
startNextImportProcess();
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemLibraryAssetImporter::isImporting() const
|
bool ItemLibraryAssetImporter::isImporting() const
|
||||||
{
|
{
|
||||||
return m_isImporting;
|
return m_isImporting;
|
||||||
@@ -104,19 +150,19 @@ void ItemLibraryAssetImporter::cancelImport()
|
|||||||
notifyFinished();
|
notifyFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImporter::addError(const QString &errMsg, const QString &srcPath) const
|
void ItemLibraryAssetImporter::addError(const QString &errMsg, const QString &srcPath)
|
||||||
{
|
{
|
||||||
qCDebug(importerLog) << "Error: "<< errMsg << srcPath;
|
qCDebug(importerLog) << "Error: "<< errMsg << srcPath;
|
||||||
emit errorReported(errMsg, srcPath);
|
emit errorReported(errMsg, srcPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImporter::addWarning(const QString &warningMsg, const QString &srcPath) const
|
void ItemLibraryAssetImporter::addWarning(const QString &warningMsg, const QString &srcPath)
|
||||||
{
|
{
|
||||||
qCDebug(importerLog) << "Warning: " << warningMsg << srcPath;
|
qCDebug(importerLog) << "Warning: " << warningMsg << srcPath;
|
||||||
emit warningReported(warningMsg, srcPath);
|
emit warningReported(warningMsg, srcPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &srcPath) const
|
void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &srcPath)
|
||||||
{
|
{
|
||||||
qCDebug(importerLog) << "Info: " << infoMsg << srcPath;
|
qCDebug(importerLog) << "Info: " << infoMsg << srcPath;
|
||||||
emit infoReported(infoMsg, srcPath);
|
emit infoReported(infoMsg, srcPath);
|
||||||
@@ -127,8 +173,8 @@ void ItemLibraryAssetImporter::importProcessFinished([[maybe_unused]] int exitCo
|
|||||||
{
|
{
|
||||||
m_puppetProcess.reset();
|
m_puppetProcess.reset();
|
||||||
|
|
||||||
if (m_parseData.contains(m_currentImportId)) {
|
if (m_importIdToAssetNameMap.contains(m_currentImportId)) {
|
||||||
const ParseData &pd = m_parseData[m_currentImportId];
|
const ParseData &pd = m_parseData[m_importIdToAssetNameMap[m_currentImportId]];
|
||||||
QString errStr;
|
QString errStr;
|
||||||
if (exitStatus == QProcess::ExitStatus::CrashExit) {
|
if (exitStatus == QProcess::ExitStatus::CrashExit) {
|
||||||
errStr = tr("Import process crashed.");
|
errStr = tr("Import process crashed.");
|
||||||
@@ -151,11 +197,12 @@ void ItemLibraryAssetImporter::importProcessFinished([[maybe_unused]] int exitCo
|
|||||||
addError(tr("Asset import process failed: \"%1\".")
|
addError(tr("Asset import process failed: \"%1\".")
|
||||||
.arg(pd.sourceInfo.absoluteFilePath()));
|
.arg(pd.sourceInfo.absoluteFilePath()));
|
||||||
addError(errStr);
|
addError(errStr);
|
||||||
m_parseData.remove(m_currentImportId);
|
m_parseData.remove(m_importIdToAssetNameMap[m_currentImportId]);
|
||||||
|
m_importIdToAssetNameMap.remove(m_currentImportId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int finishedCount = m_parseData.size() - m_puppetQueue.size();
|
int finishedCount = m_importIdToAssetNameMap.size() - m_puppetQueue.size();
|
||||||
if (!m_puppetQueue.isEmpty())
|
if (!m_puppetQueue.isEmpty())
|
||||||
startNextImportProcess();
|
startNextImportProcess();
|
||||||
|
|
||||||
@@ -163,7 +210,7 @@ void ItemLibraryAssetImporter::importProcessFinished([[maybe_unused]] int exitCo
|
|||||||
notifyProgress(100);
|
notifyProgress(100);
|
||||||
QTimer::singleShot(0, this, &ItemLibraryAssetImporter::postImport);
|
QTimer::singleShot(0, this, &ItemLibraryAssetImporter::postImport);
|
||||||
} else {
|
} else {
|
||||||
notifyProgress(int(100. * (double(finishedCount) / double(m_parseData.size()))));
|
notifyProgress(int(100. * (double(finishedCount) / double(m_importIdToAssetNameMap.size()))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +226,7 @@ void ItemLibraryAssetImporter::reset()
|
|||||||
m_cancelled = false;
|
m_cancelled = false;
|
||||||
|
|
||||||
delete m_tempDir;
|
delete m_tempDir;
|
||||||
m_tempDir = new QTemporaryDir;
|
m_tempDir = new QTemporaryDir(QDir::tempPath() + tempDirNameBase());
|
||||||
m_importFiles.clear();
|
m_importFiles.clear();
|
||||||
m_overwrittenImports.clear();
|
m_overwrittenImports.clear();
|
||||||
m_puppetProcess.reset();
|
m_puppetProcess.reset();
|
||||||
@@ -187,6 +234,7 @@ void ItemLibraryAssetImporter::reset()
|
|||||||
m_requiredImports.clear();
|
m_requiredImports.clear();
|
||||||
m_currentImportId = 0;
|
m_currentImportId = 0;
|
||||||
m_puppetQueue.clear();
|
m_puppetQueue.clear();
|
||||||
|
m_importIdToAssetNameMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
||||||
@@ -208,9 +256,11 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
|||||||
int index = extToImportOptionsMap.value(QFileInfo(file).suffix());
|
int index = extToImportOptionsMap.value(QFileInfo(file).suffix());
|
||||||
ParseData pd;
|
ParseData pd;
|
||||||
pd.options = options[index];
|
pd.options = options[index];
|
||||||
|
pd.optionsIndex = index;
|
||||||
if (preParseQuick3DAsset(file, pd, preselectedFilesForOverwrite)) {
|
if (preParseQuick3DAsset(file, pd, preselectedFilesForOverwrite)) {
|
||||||
pd.importId = ++m_importIdCounter;
|
pd.importId = ++m_importIdCounter;
|
||||||
m_parseData.insert(pd.importId, pd);
|
m_importIdToAssetNameMap[pd.importId] = pd.assetName;
|
||||||
|
m_parseData.insert(pd.assetName, pd);
|
||||||
}
|
}
|
||||||
notifyProgress(qRound(++count * quota), progressTitle);
|
notifyProgress(qRound(++count * quota), progressTitle);
|
||||||
}
|
}
|
||||||
@@ -239,7 +289,7 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa
|
|||||||
|
|
||||||
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
||||||
|
|
||||||
if (pd.outDir.exists(pd.assetName)) {
|
if (m_parseData.contains(pd.assetName)) {
|
||||||
addWarning(tr("Skipped import of duplicate asset: \"%1\".").arg(pd.assetName));
|
addWarning(tr("Skipped import of duplicate asset: \"%1\".").arg(pd.assetName));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -288,11 +338,12 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pd.outDir.mkpath(pd.assetName);
|
QString assetFolder = generateAssetFolderName(pd.assetName);
|
||||||
|
pd.outDir.mkpath(assetFolder);
|
||||||
|
|
||||||
if (!pd.outDir.cd(pd.assetName)) {
|
if (!pd.outDir.cd(assetFolder)) {
|
||||||
addError(tr("Could not access temporary asset directory: \"%1\".")
|
addError(tr("Could not access temporary asset directory: \"%1\".")
|
||||||
.arg(pd.outDir.filePath(pd.assetName)));
|
.arg(pd.outDir.filePath(assetFolder)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -425,7 +476,7 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd)
|
|||||||
|
|
||||||
// Copy the original asset into a subdirectory
|
// Copy the original asset into a subdirectory
|
||||||
assetFiles.insert(sourcePath, sourceSceneTargetFilePath(pd));
|
assetFiles.insert(sourcePath, sourceSceneTargetFilePath(pd));
|
||||||
m_importFiles.insert(assetFiles);
|
m_importFiles.insert(pd.assetName, assetFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImporter::copyImportedFiles()
|
void ItemLibraryAssetImporter::copyImportedFiles()
|
||||||
@@ -500,6 +551,12 @@ void ItemLibraryAssetImporter::keepUiAlive() const
|
|||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ItemLibraryAssetImporter::generateAssetFolderName(const QString &assetName) const
|
||||||
|
{
|
||||||
|
static int counter = 0;
|
||||||
|
return assetName + "_QDS_" + QString::number(counter++);
|
||||||
|
}
|
||||||
|
|
||||||
ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName)
|
ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName)
|
||||||
{
|
{
|
||||||
const QString title = tr("Overwrite Existing Asset?");
|
const QString title = tr("Overwrite Existing Asset?");
|
||||||
@@ -534,7 +591,8 @@ void ItemLibraryAssetImporter::startNextImportProcess()
|
|||||||
if (model && view) {
|
if (model && view) {
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while (!m_puppetQueue.isEmpty() && !done) {
|
while (!m_puppetQueue.isEmpty() && !done) {
|
||||||
const ParseData pd = m_parseData.value(m_puppetQueue.takeLast());
|
const ParseData pd = m_parseData.value(
|
||||||
|
m_importIdToAssetNameMap.value(m_puppetQueue.takeLast()));
|
||||||
QStringList puppetArgs;
|
QStringList puppetArgs;
|
||||||
QJsonDocument optDoc(pd.options);
|
QJsonDocument optDoc(pd.options);
|
||||||
|
|
||||||
@@ -557,7 +615,8 @@ void ItemLibraryAssetImporter::startNextImportProcess()
|
|||||||
} else {
|
} else {
|
||||||
addError(tr("Failed to start import 3D asset process."),
|
addError(tr("Failed to start import 3D asset process."),
|
||||||
pd.sourceInfo.absoluteFilePath());
|
pd.sourceInfo.absoluteFilePath());
|
||||||
m_parseData.remove(pd.importId);
|
const QString assetName = m_importIdToAssetNameMap.take(pd.importId);
|
||||||
|
m_parseData.remove(assetName);
|
||||||
m_puppetProcess.reset();
|
m_puppetProcess.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,8 +632,16 @@ void ItemLibraryAssetImporter::postImport()
|
|||||||
postParseQuick3DAsset(pd);
|
postParseQuick3DAsset(pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCancelled())
|
if (!isCancelled()) {
|
||||||
|
// TODO: Currently we only support import preview for single imports
|
||||||
|
if (m_parseData.size() != 1) {
|
||||||
finalizeQuick3DImport();
|
finalizeQuick3DImport();
|
||||||
|
} else {
|
||||||
|
const ParseData &pd = m_parseData[m_parseData.keys().first()];
|
||||||
|
const QString importedComponentName = pd.assetName;
|
||||||
|
emit importReadyForPreview(pd.outDir.absolutePath(), importedComponentName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "import.h"
|
|
||||||
|
|
||||||
#include <qprocessuniqueptr.h>
|
#include <qprocessuniqueptr.h>
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
@@ -35,20 +33,28 @@ public:
|
|||||||
const QHash<QString, int> &extToImportOptionsMap,
|
const QHash<QString, int> &extToImportOptionsMap,
|
||||||
const QSet<QString> &preselectedFilesForOverwrite);
|
const QSet<QString> &preselectedFilesForOverwrite);
|
||||||
|
|
||||||
|
void reImportQuick3D(const QString &assetName, const QVector<QJsonObject> &options);
|
||||||
|
|
||||||
bool isImporting() const;
|
bool isImporting() const;
|
||||||
void cancelImport();
|
void cancelImport();
|
||||||
bool isCancelled() const;
|
bool isCancelled() const;
|
||||||
|
|
||||||
void addError(const QString &errMsg, const QString &srcPath = {}) const;
|
void addError(const QString &errMsg, const QString &srcPath = {});
|
||||||
void addWarning(const QString &warningMsg, const QString &srcPath = {}) const;
|
void addWarning(const QString &warningMsg, const QString &srcPath = {});
|
||||||
void addInfo(const QString &infoMsg, const QString &srcPath = {}) const;
|
void addInfo(const QString &infoMsg, const QString &srcPath = {});
|
||||||
|
|
||||||
|
QString previewFileName() const { return "QDSImport3dPreviewScene.qml"; }
|
||||||
|
QString tempDirNameBase() const { return "/qds3dimport"; }
|
||||||
|
|
||||||
|
void finalizeQuick3DImport();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorReported(const QString &, const QString &) const;
|
void errorReported(const QString &, const QString &);
|
||||||
void warningReported(const QString &, const QString &) const;
|
void warningReported(const QString &, const QString &);
|
||||||
void infoReported(const QString &, const QString &) const;
|
void infoReported(const QString &, const QString &);
|
||||||
void progressChanged(int value, const QString &text) const;
|
void progressChanged(int value, const QString &text);
|
||||||
void importNearlyFinished() const;
|
void importReadyForPreview(const QString &path, const QString &compName);
|
||||||
|
void importNearlyFinished();
|
||||||
void importFinished();
|
void importFinished();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@@ -63,7 +69,8 @@ private:
|
|||||||
QFileInfo sourceInfo;
|
QFileInfo sourceInfo;
|
||||||
QString assetName;
|
QString assetName;
|
||||||
QString originalAssetName;
|
QString originalAssetName;
|
||||||
int importId;
|
int importId = -1;
|
||||||
|
int optionsIndex = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void notifyFinished();
|
void notifyFinished();
|
||||||
@@ -79,6 +86,7 @@ private:
|
|||||||
void notifyProgress(int value, const QString &text);
|
void notifyProgress(int value, const QString &text);
|
||||||
void notifyProgress(int value);
|
void notifyProgress(int value);
|
||||||
void keepUiAlive() const;
|
void keepUiAlive() const;
|
||||||
|
QString generateAssetFolderName(const QString &assetName) const;
|
||||||
|
|
||||||
enum class OverwriteResult {
|
enum class OverwriteResult {
|
||||||
Skip,
|
Skip,
|
||||||
@@ -89,10 +97,9 @@ private:
|
|||||||
OverwriteResult confirmAssetOverwrite(const QString &assetName);
|
OverwriteResult confirmAssetOverwrite(const QString &assetName);
|
||||||
void startNextImportProcess();
|
void startNextImportProcess();
|
||||||
void postImport();
|
void postImport();
|
||||||
void finalizeQuick3DImport();
|
|
||||||
QString sourceSceneTargetFilePath(const ParseData &pd);
|
QString sourceSceneTargetFilePath(const ParseData &pd);
|
||||||
|
|
||||||
QSet<QHash<QString, QString>> m_importFiles;
|
QHash<QString, QHash<QString, QString>> m_importFiles; // Key: asset name
|
||||||
QHash<QString, QStringList> m_overwrittenImports;
|
QHash<QString, QStringList> m_overwrittenImports;
|
||||||
bool m_isImporting = false;
|
bool m_isImporting = false;
|
||||||
bool m_cancelled = false;
|
bool m_cancelled = false;
|
||||||
@@ -101,7 +108,8 @@ private:
|
|||||||
QProcessUniquePointer m_puppetProcess;
|
QProcessUniquePointer m_puppetProcess;
|
||||||
int m_importIdCounter = 0;
|
int m_importIdCounter = 0;
|
||||||
int m_currentImportId = 0;
|
int m_currentImportId = 0;
|
||||||
QHash<int, ParseData> m_parseData;
|
QHash<int, QString> m_importIdToAssetNameMap;
|
||||||
|
QHash<QString, ParseData> m_parseData; // Key: asset name
|
||||||
QString m_progressTitle;
|
QString m_progressTitle;
|
||||||
QStringList m_requiredImports;
|
QStringList m_requiredImports;
|
||||||
QList<int> m_puppetQueue;
|
QList<int> m_puppetQueue;
|
||||||
|
@@ -164,7 +164,7 @@ void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap)
|
|||||||
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
|
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
|
||||||
m_importableExtensions3DMap,
|
m_importableExtensions3DMap,
|
||||||
m_importOptions3DMap, {}, {},
|
m_importOptions3DMap, {}, {},
|
||||||
Core::ICore::dialogParent());
|
this, Core::ICore::dialogParent());
|
||||||
int result = importDlg->exec();
|
int result = importDlg->exec();
|
||||||
|
|
||||||
return result == QDialog::Accepted ? AddFilesResult::succeeded() : AddFilesResult::cancelled();
|
return result == QDialog::Accepted ? AddFilesResult::succeeded() : AddFilesResult::cancelled();
|
||||||
@@ -198,7 +198,7 @@ void ItemLibraryView::customNotification(const AbstractView *view, const QString
|
|||||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||||
{
|
{
|
||||||
if (identifier == "UpdateImported3DAsset" && nodeList.size() > 0) {
|
if (identifier == "UpdateImported3DAsset" && nodeList.size() > 0) {
|
||||||
ItemLibraryAssetImportDialog::updateImport(nodeList[0],
|
ItemLibraryAssetImportDialog::updateImport(this, nodeList[0],
|
||||||
m_importableExtensions3DMap,
|
m_importableExtensions3DMap,
|
||||||
m_importOptions3DMap);
|
m_importOptions3DMap);
|
||||||
|
|
||||||
|
@@ -39,7 +39,8 @@ namespace Internal {
|
|||||||
|
|
||||||
static QStringList puppetModes()
|
static QStringList puppetModes()
|
||||||
{
|
{
|
||||||
static QStringList puppetModeList{"", "all", "editormode", "rendermode", "previewmode", "bakelightsmode"};
|
static QStringList puppetModeList{"", "all", "editormode", "rendermode", "previewmode",
|
||||||
|
"bakelightsmode", "import3dmode"};
|
||||||
return puppetModeList;
|
return puppetModeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,6 +140,7 @@ extend_qtc_executable(qml2puppet
|
|||||||
qmltransitionnodeinstance.cpp qmltransitionnodeinstance.h
|
qmltransitionnodeinstance.cpp qmltransitionnodeinstance.h
|
||||||
qt3dpresentationnodeinstance.cpp qt3dpresentationnodeinstance.h
|
qt3dpresentationnodeinstance.cpp qt3dpresentationnodeinstance.h
|
||||||
qt5bakelightsnodeinstanceserver.cpp qt5bakelightsnodeinstanceserver.h
|
qt5bakelightsnodeinstanceserver.cpp qt5bakelightsnodeinstanceserver.h
|
||||||
|
qt5import3dnodeinstanceserver.cpp qt5import3dnodeinstanceserver.h
|
||||||
qt5informationnodeinstanceserver.cpp qt5informationnodeinstanceserver.h
|
qt5informationnodeinstanceserver.cpp qt5informationnodeinstanceserver.h
|
||||||
qt5nodeinstanceclientproxy.cpp qt5nodeinstanceclientproxy.h
|
qt5nodeinstanceclientproxy.cpp qt5nodeinstanceclientproxy.h
|
||||||
qt5nodeinstanceserver.cpp qt5nodeinstanceserver.h
|
qt5nodeinstanceserver.cpp qt5nodeinstanceserver.h
|
||||||
|
@@ -462,7 +462,7 @@ QVector4D GeneralHelper::approachNode(
|
|||||||
// a selection box for bound calculations to work. This is used to focus the view for
|
// a selection box for bound calculations to work. This is used to focus the view for
|
||||||
// various preview image generations, where doing things asynchronously is not good
|
// various preview image generations, where doing things asynchronously is not good
|
||||||
// and recalculating bounds for every frame is not a problem.
|
// and recalculating bounds for every frame is not a problem.
|
||||||
void GeneralHelper::calculateNodeBoundsAndFocusCamera(
|
QVector3D GeneralHelper::calculateNodeBoundsAndFocusCamera(
|
||||||
QQuick3DCamera *camera, QQuick3DNode *node, QQuick3DViewport *viewPort,
|
QQuick3DCamera *camera, QQuick3DNode *node, QQuick3DViewport *viewPort,
|
||||||
float defaultLookAtDistance, bool closeUp)
|
float defaultLookAtDistance, bool closeUp)
|
||||||
{
|
{
|
||||||
@@ -505,8 +505,9 @@ void GeneralHelper::calculateNodeBoundsAndFocusCamera(
|
|||||||
perspectiveCamera->setClipNear(minDist * 0.99);
|
perspectiveCamera->setClipNear(minDist * 0.99);
|
||||||
perspectiveCamera->setClipFar(maxDist * 1.01);
|
perspectiveCamera->setClipFar(maxDist * 1.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return extents;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aligns any cameras found in nodes list to a camera.
|
// Aligns any cameras found in nodes list to a camera.
|
||||||
|
@@ -72,9 +72,11 @@ public:
|
|||||||
bool closeUp = false);
|
bool closeUp = false);
|
||||||
Q_INVOKABLE QVector4D approachNode(QQuick3DCamera *camera, float defaultLookAtDistance,
|
Q_INVOKABLE QVector4D approachNode(QQuick3DCamera *camera, float defaultLookAtDistance,
|
||||||
QObject *node, QQuick3DViewport *viewPort);
|
QObject *node, QQuick3DViewport *viewPort);
|
||||||
Q_INVOKABLE void calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
|
Q_INVOKABLE QVector3D calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera,
|
||||||
|
QQuick3DNode *node,
|
||||||
QQuick3DViewport *viewPort,
|
QQuick3DViewport *viewPort,
|
||||||
float defaultLookAtDistance, bool closeUp);
|
float defaultLookAtDistance,
|
||||||
|
bool closeUp);
|
||||||
Q_INVOKABLE void alignCameras(QQuick3DCamera *camera, const QVariant &nodes);
|
Q_INVOKABLE void alignCameras(QQuick3DCamera *camera, const QVariant &nodes);
|
||||||
Q_INVOKABLE QVector4D alignView(QQuick3DCamera *camera, const QVariant &nodes,
|
Q_INVOKABLE QVector4D alignView(QQuick3DCamera *camera, const QVariant &nodes,
|
||||||
const QVector3D &lookAtPoint, float defaultLookAtDistance);
|
const QVector3D &lookAtPoint, float defaultLookAtDistance);
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include "qt5bakelightsnodeinstanceserver.h"
|
#include "qt5bakelightsnodeinstanceserver.h"
|
||||||
#include "qt5captureimagenodeinstanceserver.h"
|
#include "qt5captureimagenodeinstanceserver.h"
|
||||||
#include "qt5capturepreviewnodeinstanceserver.h"
|
#include "qt5capturepreviewnodeinstanceserver.h"
|
||||||
|
#include "qt5import3dnodeinstanceserver.h"
|
||||||
#include "qt5informationnodeinstanceserver.h"
|
#include "qt5informationnodeinstanceserver.h"
|
||||||
#include "qt5rendernodeinstanceserver.h"
|
#include "qt5rendernodeinstanceserver.h"
|
||||||
|
|
||||||
@@ -173,6 +174,8 @@ std::unique_ptr<NodeInstanceServer> createNodeInstanceServer(
|
|||||||
return std::make_unique<Qt5PreviewNodeInstanceServer>(nodeInstanceClient);
|
return std::make_unique<Qt5PreviewNodeInstanceServer>(nodeInstanceClient);
|
||||||
else if (serverName == "bakelightsmode")
|
else if (serverName == "bakelightsmode")
|
||||||
return std::make_unique<Qt5BakeLightsNodeInstanceServer>(nodeInstanceClient);
|
return std::make_unique<Qt5BakeLightsNodeInstanceServer>(nodeInstanceClient);
|
||||||
|
else if (serverName == "import3dmode")
|
||||||
|
return std::make_unique<Qt5Import3dNodeInstanceServer>(nodeInstanceClient);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,186 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "qt5import3dnodeinstanceserver.h"
|
||||||
|
|
||||||
|
#include "createscenecommand.h"
|
||||||
|
#include "view3dactioncommand.h"
|
||||||
|
|
||||||
|
#include "imagecontainer.h"
|
||||||
|
#include "nodeinstanceclientinterface.h"
|
||||||
|
#include "puppettocreatorcommand.h"
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
#include <QQmlProperty>
|
||||||
|
|
||||||
|
#include <private/qquick3dnode_p.h>
|
||||||
|
#include <private/qquick3dviewport_p.h>
|
||||||
|
#include <private/qquickdesignersupport_p.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
Qt5Import3dNodeInstanceServer::Qt5Import3dNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
|
||||||
|
Qt5NodeInstanceServer(nodeInstanceClient)
|
||||||
|
{
|
||||||
|
setSlowRenderTimerInterval(100000000);
|
||||||
|
setRenderTimerInterval(20);
|
||||||
|
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
m_generalHelper = new Internal::GeneralHelper();
|
||||||
|
QObject::connect(m_generalHelper, &Internal::GeneralHelper::requestRender, this, [this]() {
|
||||||
|
startRenderTimer();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt5Import3dNodeInstanceServer::~Qt5Import3dNodeInstanceServer()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::createScene(const CreateSceneCommand &command)
|
||||||
|
{
|
||||||
|
initializeView();
|
||||||
|
registerFonts(command.resourceUrl);
|
||||||
|
setTranslationLanguage(command.language);
|
||||||
|
setupScene(command);
|
||||||
|
startRenderTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DActionCommand &command)
|
||||||
|
{
|
||||||
|
switch (command.type()) {
|
||||||
|
case View3DActionType::Import3dUpdatePreviewImage: {
|
||||||
|
QObject *obj = rootItem();
|
||||||
|
if (obj) {
|
||||||
|
QSize size = command.value().toSize();
|
||||||
|
QQmlProperty wProp(obj, "width", context());
|
||||||
|
QQmlProperty hProp(obj, "height", context());
|
||||||
|
wProp.write(size.width());
|
||||||
|
hProp.write(size.height());
|
||||||
|
resizeCanvasToRootItem();
|
||||||
|
|
||||||
|
startRenderTimer();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::startRenderTimer()
|
||||||
|
{
|
||||||
|
if (timerId() != 0)
|
||||||
|
killTimer(timerId());
|
||||||
|
|
||||||
|
int timerId = startTimer(renderTimerInterval());
|
||||||
|
|
||||||
|
setTimerId(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::cleanup()
|
||||||
|
{
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
delete m_previewNode;
|
||||||
|
delete m_generalHelper;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::finish()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::collectItemChangesAndSendChangeCommands()
|
||||||
|
{
|
||||||
|
static bool inFunction = false;
|
||||||
|
|
||||||
|
if (!rootNodeInstance().holdsGraphical())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!inFunction) {
|
||||||
|
inFunction = true;
|
||||||
|
|
||||||
|
QQuickDesignerSupport::polishItems(quickWindow());
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
inFunction = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5Import3dNodeInstanceServer::render()
|
||||||
|
{
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
++m_renderCount;
|
||||||
|
|
||||||
|
if (m_renderCount == 1) {
|
||||||
|
QObject *obj = rootItem();
|
||||||
|
QQmlProperty viewProp(obj, "view3d", context());
|
||||||
|
QObject *viewObj = viewProp.read().value<QObject *>();
|
||||||
|
m_view3D = qobject_cast<QQuick3DViewport *>(viewObj);
|
||||||
|
if (m_view3D) {
|
||||||
|
QQmlProperty sceneModelNameProp(obj, "sceneModelName", context());
|
||||||
|
QString sceneModelName = sceneModelNameProp.read().toString();
|
||||||
|
QFileInfo fi(fileUrl().toLocalFile());
|
||||||
|
QString compPath = fi.absolutePath() + '/' + sceneModelName + ".qml";
|
||||||
|
QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous);
|
||||||
|
m_previewNode = qobject_cast<QQuick3DNode *>(comp.create(context()));
|
||||||
|
if (m_previewNode) {
|
||||||
|
engine()->setObjectOwnership(m_previewNode, QJSEngine::CppOwnership);
|
||||||
|
m_previewNode->setParent(m_view3D);
|
||||||
|
m_view3D->setImportScene(m_previewNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render scene once to ensure geometries are intialized so bounds calculations work correctly
|
||||||
|
if (m_renderCount == 2 && m_view3D) {
|
||||||
|
QVector3D extents =
|
||||||
|
m_generalHelper->calculateNodeBoundsAndFocusCamera(m_view3D->camera(), m_previewNode,
|
||||||
|
m_view3D, 1040, false);
|
||||||
|
auto getExtentStr = [&extents](int idx) -> QString {
|
||||||
|
int prec = 0;
|
||||||
|
float val = extents[idx];
|
||||||
|
while (val < 100.f) {
|
||||||
|
++prec;
|
||||||
|
val *= 10.f;
|
||||||
|
}
|
||||||
|
// Strip unnecessary zeroes after decimal separator
|
||||||
|
if (prec > 0) {
|
||||||
|
QString checkStr = QString::number(extents[idx], 'f', prec);
|
||||||
|
while (prec > 0 && (checkStr.last(1) == "0" || checkStr.last(1) == ".")) {
|
||||||
|
--prec;
|
||||||
|
checkStr.chop(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString retval = QLocale().toString(extents[idx], 'f', prec);
|
||||||
|
return retval;
|
||||||
|
};
|
||||||
|
QQmlProperty extentsProp(rootItem(), "extents", context());
|
||||||
|
extentsProp.write(tr("Dimensions: %1 x %2 x %3").arg(getExtentStr(0))
|
||||||
|
.arg(getExtentStr(1))
|
||||||
|
.arg(getExtentStr(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
rootNodeInstance().updateDirtyNodeRecursive();
|
||||||
|
QImage renderImage = grabWindow();
|
||||||
|
|
||||||
|
if (m_renderCount >= 2) {
|
||||||
|
ImageContainer imgContainer(0, renderImage, m_renderCount);
|
||||||
|
nodeInstanceClient()->handlePuppetToCreatorCommand(
|
||||||
|
{PuppetToCreatorCommand::Import3DPreviewImage,
|
||||||
|
QVariant::fromValue(imgContainer)});
|
||||||
|
slowDownRenderTimer(); // No more renders needed for now
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
slowDownRenderTimer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "generalhelper.h"
|
||||||
|
#include "qt5nodeinstanceserver.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QQuick3DNode;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class Qt5Import3dNodeInstanceServer : public Qt5NodeInstanceServer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Qt5Import3dNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Qt5Import3dNodeInstanceServer();
|
||||||
|
|
||||||
|
void createScene(const CreateSceneCommand &command) override;
|
||||||
|
void view3DAction(const View3DActionCommand &command) override;
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void collectItemChangesAndSendChangeCommands() override;
|
||||||
|
void startRenderTimer() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void finish();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
int m_renderCount = 0;
|
||||||
|
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
QQuick3DViewport *m_view3D = nullptr;
|
||||||
|
Internal::GeneralHelper *m_generalHelper = nullptr;
|
||||||
|
QQuick3DNode *m_previewNode = nullptr;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -10,6 +10,7 @@
|
|||||||
#include "qt5captureimagenodeinstanceserver.h"
|
#include "qt5captureimagenodeinstanceserver.h"
|
||||||
#include "qt5capturepreviewnodeinstanceserver.h"
|
#include "qt5capturepreviewnodeinstanceserver.h"
|
||||||
#include "qt5informationnodeinstanceserver.h"
|
#include "qt5informationnodeinstanceserver.h"
|
||||||
|
#include "qt5import3dnodeinstanceserver.h"
|
||||||
#include "qt5previewnodeinstanceserver.h"
|
#include "qt5previewnodeinstanceserver.h"
|
||||||
#include "qt5rendernodeinstanceserver.h"
|
#include "qt5rendernodeinstanceserver.h"
|
||||||
#include "qt5testnodeinstanceserver.h"
|
#include "qt5testnodeinstanceserver.h"
|
||||||
@@ -70,6 +71,9 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
|
|||||||
} else if (QCoreApplication::arguments().at(2) == QLatin1String("bakelightsmode")) {
|
} else if (QCoreApplication::arguments().at(2) == QLatin1String("bakelightsmode")) {
|
||||||
setNodeInstanceServer(std::make_unique<Qt5BakeLightsNodeInstanceServer>(this));
|
setNodeInstanceServer(std::make_unique<Qt5BakeLightsNodeInstanceServer>(this));
|
||||||
initializeSocket();
|
initializeSocket();
|
||||||
|
} else if (QCoreApplication::arguments().at(2) == QLatin1String("import3dmode")) {
|
||||||
|
setNodeInstanceServer(std::make_unique<Qt5Import3dNodeInstanceServer>(this));
|
||||||
|
initializeSocket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user