QmlDesigner: Move assignMaterialTo3dModel() to a utils class

In order to avoid dependency of AbstractView on QmlObjectNode. Moreover,
it seems not in the right place anymore since it is not really part of
an abstract code.

Change-Id: I7a64122e6ab0a2e314c593f0f47dadaa07d772e2
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Mahmoud Badri
2023-03-21 12:54:36 +02:00
parent cb0fc5fd1f
commit 46b0aaeebe
9 changed files with 104 additions and 64 deletions

View File

@@ -825,6 +825,7 @@ extend_qtc_plugin(QmlDesigner
materialbrowserwidget.cpp materialbrowserwidget.h
materialbrowsermodel.cpp materialbrowsermodel.h
materialbrowsertexturesmodel.cpp materialbrowsertexturesmodel.h
materialutils.cpp materialutils.h
)
extend_qtc_plugin(QmlDesigner

View File

@@ -12,6 +12,7 @@
#include "edit3dcanvas.h"
#include "edit3dviewconfig.h"
#include "edit3dwidget.h"
#include "materialutils.h"
#include "metainfo.h"
#include "nodehints.h"
#include "nodeinstanceview.h"
@@ -324,7 +325,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
createdNode = QmlVisualNode::createQml3DNode(
this, m_droppedEntry, edit3DWidget()->canvas()->activeScene(), pos3d).modelNode();
if (createdNode.metaInfo().isQtQuick3DModel())
assignMaterialTo3dModel(createdNode);
MaterialUtils::assignMaterialTo3dModel(this, createdNode);
});
if (createdNode.isValid())
setSelectedModelNode(createdNode);
@@ -332,7 +333,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
if (m_droppedModelNode.isValid() && isModel) {
executeInTransaction(__FUNCTION__, [&] {
assignMaterialTo3dModel(modelNode, m_droppedModelNode);
MaterialUtils::assignMaterialTo3dModel(this, modelNode, m_droppedModelNode);
});
}
} else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) {

View File

@@ -8,6 +8,7 @@
#include "edit3dcanvas.h"
#include "edit3dview.h"
#include "edit3dvisibilitytogglesmenu.h"
#include "materialutils.h"
#include "metainfo.h"
#include "modelnodeoperations.h"
#include "nodeabstractproperty.h"
@@ -387,7 +388,7 @@ void Edit3DWidget::onCreateAction()
// if added node is a Model, assign it a material
if (modelNode.metaInfo().isQtQuick3DModel())
m_view->assignMaterialTo3dModel(modelNode);
MaterialUtils::assignMaterialTo3dModel(m_view, modelNode);
});
}

View File

@@ -7,6 +7,7 @@
#include "formeditorview.h"
#include "assetslibrarywidget.h"
#include "assetslibrarymodel.h"
#include "materialutils.h"
#include <metainfo.h>
#include <modelnodeoperations.h>
#include <nodehints.h>
@@ -441,7 +442,7 @@ void DragTool::handleView3dDrop()
const QList<ModelNode> models = dragNode.modelNode().subModelNodesOfType(
model->qtQuick3DModelMetaInfo());
QTC_ASSERT(models.size() == 1, return);
view()->assignMaterialTo3dModel(models.at(0));
MaterialUtils::assignMaterialTo3dModel(view(), models.at(0));
}
}
}

View File

@@ -0,0 +1,71 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "materialutils.h"
#include "abstractview.h"
#include "nodelistproperty.h"
#include "nodemetainfo.h"
#include "qmlobjectnode.h"
#include "variantproperty.h"
#include <utils/qtcassert.h>
namespace QmlDesigner {
// Assigns given material to a 3D model.
// The assigned material is also inserted into material library if not already there.
// If given material is not valid, first existing material from material library is used,
// or if material library is empty, a new material is created.
// This function should be called only from inside a transaction, as it potentially does many
// changes to model.
void MaterialUtils::assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode,
const ModelNode &materialNode)
{
QTC_ASSERT(modelNode.isValid() && modelNode.metaInfo().isQtQuick3DModel(), return);
ModelNode matLib = view->materialLibraryNode();
if (!matLib.isValid())
return;
ModelNode newMaterialNode;
if (materialNode.isValid() && materialNode.metaInfo().isQtQuick3DMaterial()) {
newMaterialNode = materialNode;
} else {
const QList<ModelNode> materials = matLib.directSubModelNodes();
if (materials.size() > 0) {
for (const ModelNode &mat : materials) {
if (mat.metaInfo().isQtQuick3DMaterial()) {
newMaterialNode = mat;
break;
}
}
}
// if no valid material, create a new default material
if (!newMaterialNode.isValid()) {
NodeMetaInfo metaInfo = view->model()->qtQuick3DPrincipledMaterialMetaInfo();
newMaterialNode = view->createModelNode("QtQuick3D.PrincipledMaterial",
metaInfo.majorVersion(),
metaInfo.minorVersion());
newMaterialNode.validId();
}
}
QTC_ASSERT(newMaterialNode.isValid(), return);
VariantProperty matNameProp = newMaterialNode.variantProperty("objectName");
if (matNameProp.value().isNull())
matNameProp.setValue("New Material");
if (!newMaterialNode.hasParentProperty()
|| newMaterialNode.parentProperty() != matLib.defaultNodeListProperty()) {
matLib.defaultNodeListProperty().reparentHere(newMaterialNode);
}
QmlObjectNode(modelNode).setBindingProperty("materials", newMaterialNode.id());
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,20 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include "modelnode.h"
namespace QmlDesigner {
class AbstractView;
class MaterialUtils
{
public:
MaterialUtils();
static void assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode,
const ModelNode &materialNode = {});
};
} // namespace QmlDesigner

View File

@@ -17,6 +17,7 @@
#include <nodeproperty.h>
#include <variantproperty.h>
#include <metainfo.h>
#include <materialutils.h>
#include <abstractview.h>
#include <invalididexception.h>
#include <rewritingexception.h>
@@ -710,7 +711,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
newQmlObjectNode.destroy();
return;
}
m_view->assignMaterialTo3dModel(targetNode, newModelNode);
MaterialUtils::assignMaterialTo3dModel(m_view, targetNode, newModelNode);
}
ChooseFromPropertyListDialog *dialog = ChooseFromPropertyListDialog::createIfNeeded(
@@ -751,9 +752,9 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
const QList<ModelNode> models = newModelNode.subModelNodesOfType(
m_view->model()->qtQuick3DModelMetaInfo());
QTC_ASSERT(models.size() == 1, return);
m_view->assignMaterialTo3dModel(models.at(0));
MaterialUtils::assignMaterialTo3dModel(m_view, models.at(0));
} else if (newModelNode.metaInfo().isQtQuick3DModel()) {
m_view->assignMaterialTo3dModel(newModelNode);
MaterialUtils::assignMaterialTo3dModel(m_view, newModelNode);
}
if (!validContainer) {
@@ -836,7 +837,7 @@ void NavigatorTreeModel::handleMaterialDrop(const QMimeData *mimeData, const QMo
ModelNode matNode = m_view->modelNodeForInternalId(internalId);
m_view->executeInTransaction(__FUNCTION__, [&] {
m_view->assignMaterialTo3dModel(targetNode, matNode);
MaterialUtils::assignMaterialTo3dModel(m_view, targetNode, matNode);
});
}

View File

@@ -231,7 +231,6 @@ public:
ModelNode materialLibraryNode();
bool isPartOfMaterialLibrary(const ModelNode &node);
ModelNode active3DSceneNode();
void assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode = {});
ModelNode getTextureDefaultInstance(const QString &source);
const NodeInstanceView *nodeInstanceView() const;

View File

@@ -8,7 +8,6 @@
#include "model_p.h"
#include "internalnode_p.h"
#include "nodeinstanceview.h"
#include "qmlobjectnode.h"
#include <qmlstate.h>
#include <qmltimeline.h>
#include <nodemetainfo.h>
@@ -879,60 +878,6 @@ ModelNode AbstractView::active3DSceneNode()
return {};
}
// Assigns given material to a 3D model.
// The assigned material is also inserted into material library if not already there.
// If given material is not valid, first existing material from material library is used,
// or if material library is empty, a new material is created.
// This function should be called only from inside a transaction, as it potentially does many
// changes to model.
void AbstractView::assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode)
{
QTC_ASSERT(modelNode.isValid() && modelNode.metaInfo().isQtQuick3DModel(), return );
ModelNode matLib = materialLibraryNode();
if (!matLib.isValid())
return;
ModelNode newMaterialNode;
if (materialNode.isValid() && materialNode.metaInfo().isQtQuick3DMaterial()) {
newMaterialNode = materialNode;
} else {
const QList<ModelNode> materials = matLib.directSubModelNodes();
if (materials.size() > 0) {
for (const ModelNode &mat : materials) {
if (mat.metaInfo().isQtQuick3DMaterial()) {
newMaterialNode = mat;
break;
}
}
}
// if no valid material, create a new default material
if (!newMaterialNode.isValid()) {
NodeMetaInfo metaInfo = model()->qtQuick3DPrincipledMaterialMetaInfo();
newMaterialNode = createModelNode("QtQuick3D.PrincipledMaterial",
metaInfo.majorVersion(),
metaInfo.minorVersion());
newMaterialNode.validId();
}
}
QTC_ASSERT(newMaterialNode.isValid(), return);
VariantProperty matNameProp = newMaterialNode.variantProperty("objectName");
if (matNameProp.value().isNull())
matNameProp.setValue("New Material");
if (!newMaterialNode.hasParentProperty()
|| newMaterialNode.parentProperty() != matLib.defaultNodeListProperty()) {
matLib.defaultNodeListProperty().reparentHere(newMaterialNode);
}
QmlObjectNode(modelNode).setBindingProperty("materials", newMaterialNode.id());
}
ModelNode AbstractView::getTextureDefaultInstance(const QString &source)
{
ModelNode matLib = materialLibraryNode();