Notifications
Clear all

[Closed] Replace material in SDK

How do I go about replacing a material, and thus telling everything that it’s assigned to, to use a new material?

I could iterate through every single object to check if it has that material, but that’s a little sledgehammer’y.

2 Replies

At the very least, how do I get a list of INode’s that are referencing said IMtl?

My “solution” was to do what I didn’t want to do and check every scene node. Here’s the code (in maxdotnet):


        public static List<IINode> GetNodesByMaterialName(this IHasGlobal global, IMtl material)
        {
            var n = GetSceneNodes(global);

            if (n == null || n.Count <= 0)
                return null;

            var result = new List<IINode>();

            for (int i = 0; i < n.Count; i++)
            {
                var thisNode = n[i];
                var thisMtl = thisNode.Mtl;

                if (thisMtl == null)
                    continue;

                if (thisMtl.Name == material.Name && !result.Contains(thisNode))
                    result.Add(thisNode);
            }

            if (result.Count <= 0)
                return null;

            return result;
        }

        public static List<IINode> GetNodesByMaterial(this IHasGlobal hasGlobal, IMtl material)
        {
            var n = GetSceneNodes(hasGlobal);

            if (n == null || n.Count <= 0)
                return null;

            var result = new List<IINode>();

            for (int i = 0; i < n.Count; i++)
            {
                var thisNode = n[i];
                var thisMtl = thisNode.Mtl;

                if (thisMtl == null)
                    continue;

                if (thisMtl.Equals(material as IInterfaceServer) && !result.Contains(thisNode))
                    result.Add(thisNode);
            }

            if (result.Count <= 0)
                return null;

            return result;
        }

        public static List<IINode> GetSceneNodes(this IHasGlobal hasGlobal)
        {
            var root = hasGlobal.Global.COREInterface.RootNode;

            return GetChildNodes(hasGlobal, root, 99);
        }

        public static List<IINode> GetChildNodes(this IHasGlobal hasGlobal, IINode node, int depth)
        {
            if (depth <= 0) return null;

            var childCount = node.NumChildren;

            if (childCount == 0) return null;

            var result = new List<IINode>();

            for (var i = 0; i < childCount; i++)
            {
                var childNode = node.GetChildNode(i);
                var childObj = childNode.ObjectRef;

                if (childObj.SuperClassID == SClass_ID.Geomobject)
                    if (!result.Contains(childNode))
                        result.Add(childNode);

                var childChildNodes = GetChildNodes(hasGlobal, childNode, depth - 1);

                if (childChildNodes != null)
                    for (var j = 0; j < childChildNodes.Count; j++)
                    {
                        var childChildNode = childChildNodes[j];
                        var childChildObj = childChildNode.ObjectRef;

                        if (childChildObj.SuperClassID == SClass_ID.Geomobject)
                            if (!result.Contains(childChildNode))
                                result.Add(childChildNode);
                    }
            }

            return result;
        }