summaryrefslogtreecommitdiff
path: root/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp
blob: 76924bedbcdca7f0b9fd32e462bb827d9a1c24fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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