Results 1 to 15 of 15
  1. #1
    Member
    Join Date
    Jan 2006
    Location
    New Zealand
    Posts
    91

    Eliminate duplicate materials .001 .002 .003 after Append

    Hi Im looking for a script to eliminate multiple materials, when I Append models which use identical materials I end up with lots of duplicates, like glass, glass.001 glass.002, glass.003. ... Then I have to "Databrose" which dosnt have the nice new material previews.
    I really dont want to write my own as Im lazy and busy although I will probably end up doing so.
    Im pretty sure there isnt any way to "use existing" or "replace" materials when importing but please let me know if there is as this would help also.

    Any help appreciated.
    lobo_nz
    yet more blender scripts http://blender.formworks.co.nz/



  2. #2
    Member
    Join Date
    Mar 2006
    Location
    Istanbul
    Posts
    55
    I have the same problem when importing a wrl generated by Catia. Anything possible about this?



  3. #3
    Member Michael W's Avatar
    Join Date
    Nov 2007
    Location
    UK
    Posts
    4,992
    Here's a script I wrote for 2.49 that will "ease" this...

    (It could be modified to automatically pattern match based on name, but I personally think that could be dangerous so made it a "wizard"

    Usage?

    run the script... (I think I put it in the "objects" category rather than the materials one... but you could always run it form the text editor...

    it'll pop up a list of materials for you to choose a material to replace, then offer a similar popup for what to replace it with...

    It will then find and replace all references to the first material with the second...

    If you save the scene and reload the "replaced" material will be gone...

    Here's a link
    http://www.cowtoolsmedia.co.uk/scrip...tutemat.py.zip

    inside the script is a function:

    mw_replaceMat(inMat,outMat, allScenes =True,sel =False)

    You could import my script, build a list of materials with "auto names" and then call that function to automate it more... but the trick is when you get close to the 21 character limit and thenames have been truncated...
    Last edited by Michael W; 12-Feb-10 at 10:09.
    Mike Williamson
    www.cowtoolsmedia.co.uk



  4. #4
    How many materials have you got that are 21 characters long? I guess it could be an option to delete any of this length, 21 char (abcdefghijklmnopqrst) This is an extreme conditional but I cant really think of any other way of doing it..



  5. #5
    Member Michael W's Avatar
    Join Date
    Nov 2007
    Location
    UK
    Posts
    4,992
    Originally Posted by mandoragon View Post
    How many materials have you got that are 21 characters long? I guess it could be an option to delete any of this length, 21 char (abcdefghijklmnopqrst) This is an extreme conditional but I cant really think of any other way of doing it..
    I've done some video game work where the naming conventions imposed by the client meant that 21 characters for a material name was woefully inadequate... I ended up having to use all sorts of hacks and workarounds in blender and maya to get stuff named right once transferred to Maya...

    Which is why the "wizard" approach works for me... it only takes a few minutes for even very complex scenes.... but truncated names aside:

    a "slightly" dangerous way to do it (could potentially damage any material name with a "." if what precedes the dot is the same name as another material in the scene.

    importing my script and then doing something like the following should do what you want:

    Code:
    import bpy
    import substitutemat
    from substitutemat import*
    
    mats = bpy.data.materials
    for m in mats:
        #find the name without any auto numbered stuff:
        nm = m.name.split('.')[0]
    
    
        #check to see if the portion before the "." matches an existing material
        if nm in mats:
            mw_replaceMat(m.name, nm)
    any material names that got truncated and didn't match would have to be cleaned by just running the first script wizard I posted... which is safer I guess, and only necesary with long material names anyway!
    Last edited by Michael W; 12-Feb-10 at 11:57.
    Mike Williamson
    www.cowtoolsmedia.co.uk



  6. #6
    Member Michael W's Avatar
    Join Date
    Nov 2007
    Location
    UK
    Posts
    4,992
    Oops, of course I'm checking a list of material objects against a string! that's never match...
    Code:
    import bpy 
    import substitutemat 
    from substitutemat import* 
     
    mats = bpy.data.materials 
    #build a list of material names in the scene: 
    
    matnames = [] 
    for m in mats: 
        matnames.append(m.name) 
     
     
    for m in mats: 
        #find the name without any auto numbered stuff: 
        nm = m.name.split('.')[0] 
        #check to see if the portion before the "." matches an existing material 
        if nm in matnames: 
             mw_replaceMat(m.name, nm)
    This is about the fourth edit of this!
    Last edited by Michael W; 12-Feb-10 at 11:50. Reason: Didn't check before posting!
    Mike Williamson
    www.cowtoolsmedia.co.uk



  7. #7
    do you think we could ask the devs to increase the character limit in the next svn release? any idea why 21?



  8. #8
    Member Michael W's Avatar
    Join Date
    Nov 2007
    Location
    UK
    Posts
    4,992
    I asked Letterip ages ago... he said he'd pass it on...

    this stuff, whilst probably easy for someone to do, really takes someone to "need" it themselves to do the code... I'd patch it myself if I could code!!!!!
    Mike Williamson
    www.cowtoolsmedia.co.uk



  9. #9
    your scripting so you can code :s

    I was just assuming that the number 21 was just a variable set somewhere..



  10. #10
    Member
    Join Date
    May 2012
    Location
    Barcelona, Spain
    Posts
    584
    Any similar script to this one still in existence?



  11. #11
    Member
    Join Date
    Mar 2010
    Posts
    1,118
    here's a very basic snippet that worked for me, at least for simple scenes

    Code:
    ## 'desduplicar' materiales
    
    import bpy
    mats = bpy.data.materials
    
    for obj in bpy.data.objects:
        for slt in obj.material_slots:
            part = slt.name.rpartition('.')
            if part[2].isnumeric() and part[0] in mats:
                slt.material = mats.get(part[0])



  12. #12
    don't see it as an import script

    it only checks for same name with number at the end

    do you want to convert it as an import script too ?

    but if there are like 1000 mat this might get very sluggish !


    happy bl
    Nice 3D models = 25 % K.I.S.S + 25 % common sense + 25 % Inspiration + 25 % Knowledge
    Win 10 64 bits / Thanks and a Happy 2.79 with Cycles



  13. #13
    Member lsscpp's Avatar
    Join Date
    May 2006
    Location
    Firenze
    Posts
    2,047
    Originally Posted by liero View Post
    here's a very basic snippet that worked for me, at least for simple scenes

    Code:
    ## 'desduplicar' materiales
    
    import bpy
    mats = bpy.data.materials
    
    for obj in bpy.data.objects:
        for slt in obj.material_slots:
            part = slt.name.rpartition('.')
            if part[2].isnumeric() and part[0] in mats:
                slt.material = mats.get(part[0])
    would this work also for nodegroups, changing the appropriate bpy.data.stuff?
    Everything's relative. Even saying "Everything's relative".



  14. #14
    Member
    Join Date
    Mar 2010
    Posts
    1,118
    to deduplicate nodegroups in materials it could be something like this:
    Code:
    ## deduplicate nodegroups in materials from name
    
    import bpy
    n_gs = bpy.data.node_groups
    
    for mat in bpy.data.materials:
        for nt in mat.node_tree.nodes:
            if nt.type == 'GROUP':
                part = nt.node_tree.name.rpartition('.')
                if part[2].isnumeric() and part[0] in n_gs:
                    nt.node_tree = n_gs.get(part[0])
    but you need to be careful as it will go through all materials
    there's also the new id_remap thing meant for this situations I believe



  15. #15
    Originally Posted by liero View Post
    here's a very basic snippet that worked for me, at least for simple scenes

    Code:
    ## 'desduplicar' materiales
    
    import bpy
    mats = bpy.data.materials
    
    for obj in bpy.data.objects:
        for slt in obj.material_slots:
            part = slt.name.rpartition('.')
            if part[2].isnumeric() and part[0] in mats:
                slt.material = mats.get(part[0])
    Like a charm, thank you! In addition, I used to replace upper/lowercase duplicates:

    Code:
    for obj in bpy.data.objects:    for slt in obj.material_slots:
            if slt.name != slt.name.lower() and slt.name.lower() in mats:
                slt.material = mats.get(slt.name.lower())



Similar Threads

  1. how come i can no loner append objects and materials?
    By pixeldotz in forum Basics & Interface
    Replies: 0
    Last Post: 25-Nov-04, 18:32

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •