QmlDesigner: Don't create duplicate default texture instance

Whenever an operation involving an asset image would result in
creation of a new texture node, it now checks first if
a matching texture node already exists and uses that instead.

Fixes: QDS-8435
Change-Id: I3d091aafcd09afdec897bc4da79789c1d84056e8
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2022-11-25 17:01:53 +02:00
parent 7d13c82750
commit 5544cdc276
5 changed files with 64 additions and 16 deletions

View File

@@ -75,20 +75,29 @@ WidgetInfo ContentLibraryView::widgetInfo()
return; return;
NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.Texture"); NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.Texture");
ModelNode newTexNode = createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
metaInfo.minorVersion()); QString sourceVal = QLatin1String("images/%1").arg(texPath.split('/').last());
newTexNode.validId(); ModelNode texNode = getTextureDefaultInstance(sourceVal);
VariantProperty sourceProp = newTexNode.variantProperty("source"); if (!texNode.isValid()) {
sourceProp.setValue(QLatin1String("images/%1").arg(texPath.split('/').last())); texNode = createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
matLib.defaultNodeListProperty().reparentHere(newTexNode); metaInfo.minorVersion());
texNode.validId();
VariantProperty sourceProp = texNode.variantProperty("source");
sourceProp.setValue(sourceVal);
matLib.defaultNodeListProperty().reparentHere(texNode);
}
// assign the texture as scene environment's light probe // assign the texture as scene environment's light probe
if (mode == ContentLibraryWidget::AddTextureMode::LightProbe && m_activeSceneEnv.isValid()) { if (mode == ContentLibraryWidget::AddTextureMode::LightProbe && m_activeSceneEnv.isValid()) {
BindingProperty lightProbeProp = m_activeSceneEnv.bindingProperty("lightProbe"); BindingProperty lightProbeProp = m_activeSceneEnv.bindingProperty("lightProbe");
lightProbeProp.setExpression(newTexNode.id()); lightProbeProp.setExpression(texNode.id());
VariantProperty bgModeProp = m_activeSceneEnv.variantProperty("backgroundMode"); VariantProperty bgModeProp = m_activeSceneEnv.variantProperty("backgroundMode");
bgModeProp.setValue(QVariant::fromValue(Enumeration("SceneEnvironment", "SkyBox"))); bgModeProp.setValue(QVariant::fromValue(Enumeration("SceneEnvironment", "SkyBox")));
} }
QTimer::singleShot(0, this, [this, texNode]() {
if (model() && texNode.isValid())
emitCustomNotification("selected_texture_changed", {texNode});
});
}); });
}); });

View File

@@ -435,6 +435,10 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
int idx = m_widget->materialBrowserModel()->materialIndex(nodeList.first()); int idx = m_widget->materialBrowserModel()->materialIndex(nodeList.first());
if (idx != -1) if (idx != -1)
m_widget->materialBrowserModel()->selectMaterial(idx); m_widget->materialBrowserModel()->selectMaterial(idx);
} else if (identifier == "selected_texture_changed") {
int idx = m_widget->materialBrowserTexturesModel()->textureIndex(nodeList.first());
if (idx != -1)
m_widget->materialBrowserTexturesModel()->selectTexture(idx);
} else if (identifier == "refresh_material_browser") { } else if (identifier == "refresh_material_browser") {
QTimer::singleShot(0, model(), [this]() { QTimer::singleShot(0, model(), [this]() {
refreshModel(true); refreshModel(true);

View File

@@ -500,18 +500,28 @@ void PropertyEditorValue::commitDrop(const QString &dropData)
m_modelNode.view()->executeInTransaction(__FUNCTION__, [&] { m_modelNode.view()->executeInTransaction(__FUNCTION__, [&] {
QmlDesigner::ModelNode texture = m_modelNode.view()->modelNodeForInternalId(dropData.toInt()); QmlDesigner::ModelNode texture = m_modelNode.view()->modelNodeForInternalId(dropData.toInt());
if (!texture || !texture.metaInfo().isQtQuick3DTexture()) { if (!texture || !texture.metaInfo().isQtQuick3DTexture()) {
// create a texture node
QmlDesigner::NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo("QtQuick3D.Texture");
texture = m_modelNode.view()->createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
metaInfo.minorVersion());
texture.validId();
m_modelNode.view()->materialLibraryNode().defaultNodeListProperty().reparentHere(texture);
// set texture source
Utils::FilePath imagePath = Utils::FilePath::fromString(dropData); Utils::FilePath imagePath = Utils::FilePath::fromString(dropData);
Utils::FilePath currFilePath = QmlDesigner::DocumentManager::currentFilePath(); Utils::FilePath currFilePath = QmlDesigner::DocumentManager::currentFilePath();
QString sourceVal = imagePath.relativePathFrom(currFilePath).toString();
texture = m_modelNode.view()->getTextureDefaultInstance(sourceVal);
if (!texture.isValid()) {
// create a texture node
QmlDesigner::NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo("QtQuick3D.Texture");
texture = m_modelNode.view()->createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
metaInfo.minorVersion());
texture.validId();
m_modelNode.view()->materialLibraryNode().defaultNodeListProperty().reparentHere(texture);
}
// set texture source
QmlDesigner::VariantProperty srcProp = texture.variantProperty("source"); QmlDesigner::VariantProperty srcProp = texture.variantProperty("source");
srcProp.setValue(imagePath.relativePathFrom(currFilePath).toString()); srcProp.setValue(sourceVal);
QTimer::singleShot(0, this, [this, texture]() {
if (m_modelNode.isValid() && texture.isValid() && m_modelNode.view())
m_modelNode.view()->emitCustomNotification("selected_texture_changed", {texture});
});
} }
// assign the texture to the property // assign the texture to the property

View File

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

View File

@@ -915,6 +915,30 @@ void AbstractView::assignMaterialTo3dModel(const ModelNode &modelNode, const Mod
modelMatsProp.setExpression(newMaterialNode.id()); modelMatsProp.setExpression(newMaterialNode.id());
} }
ModelNode AbstractView::getTextureDefaultInstance(const QString &source)
{
ModelNode matLib = materialLibraryNode();
if (!matLib.isValid())
return {};
const QList <ModelNode> matLibNodes = matLib.directSubModelNodes();
for (const ModelNode &tex : matLibNodes) {
if (tex.isValid() && tex.metaInfo().isQtQuick3DTexture()) {
const QList<AbstractProperty> props = tex.properties();
if (props.size() != 1)
continue;
const AbstractProperty &prop = props[0];
if (prop.name() == "source" && prop.isVariantProperty()
&& prop.toVariantProperty().value().toString() == source) {
return tex;
}
}
}
return {};
}
ModelNode AbstractView::currentStateNode() const ModelNode AbstractView::currentStateNode() const
{ {
if (model()) if (model())