We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.

Replacing the non-primary material on a multi-material object

Home Forums Programming Replacing the non-primary material on a multi-material object

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #36440
    jem
    Customer

    I need to replace the non-primary material on a multi-material object. The replace material puzzle will only replace the first material in an object. I think that I have a reasonable solution, but I would like someone with more v3d API experience to critique my code. Here is the solution that I put together

    function prepareExternalInterface(app) {
    
        app.ExternalInterface.replaceMaterialByName = function (oldMatName, newMatName, objName) {
            v3d.apps[0].scene.getObjectByName(objName).traverse(child => {
                if (child.material) {
                    console.log(child.material.name);
                    if (child.material.name === oldMatName) {
                        console.log("replacing " + oldMatName + " with " + newMatName + " on " + child.name);
                        child.material = v3d.SceneUtils.getMaterialsByName(v3d.apps[0], newMatName)[0];
                    }
                }
            });
        }
        
    }

    Is there a better way to do this? Also, I did not .clone() the new material before applying it to the target object. In some of the three.js examples that I found, the authors would clone the material before assigning the clone to the object. Is this necessary?

    This code is in my prepareExternalInterface(). I am using “v3d.apps[0]” to obtain a reference to the current 3d app. This assumes that there is only one 3d app on the page (which might not be true). Is there a more robust way to obtain the handle of the current 3d app?
    Thanks!

    Attachments:
    You must be logged in to view attached files.

    Jeremy Wernick

    #36452

    Hi Jeremy,

    You code is OK, but you can simplify it a bit as well as fix possible issue with several apps with this code by using this code:

    app.ExternalInterface.replaceMaterialByName = function (oldMatName, newMatName, objName) {
        app.scene.getObjectByName(objName).traverse(child => {
            if (child.material) {
                console.log(child.material.name);
                if (child.material.name === oldMatName) {
                    console.log("replacing " + oldMatName + " with " + newMatName + " on " + child.name);
                    child.material = v3d.SceneUtils.getMaterialsByName(app, newMatName)[0];
                }
            }
        });
    }
    

    Cloning you materials is not required, it’s used to fix possible issues when you modify your material or mesh, e.g cases with changing color, node material animation, morphing etc.

    Soft8Soft Tech Chief
    X | FB | LinkedIn

    #36493
    jem
    Customer

    Hi Alexander,
    Thank you for the suggestions and improvements!
    I may try to implement this code as a puzzle piece using the new functionality in 3.6.

    Jeremy Wernick

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.