6
$\begingroup$

Anyone who has used Blender for a while has probably tried to duplicate a scene via Full Copy. They would have then found that in the duplicated scene, all of the materials were duplicated as well, receiving that infuriating .001 ending. Normally, one might be able to change all the materials back to the originals and then reload the file (as suggested here) to get rid of the duplicate materials. I can do this, but I have A LOT of material slots in my project, and the work is incredibly boring.

So basically, my question is...

Is there a button, script, feature, or anything else that would disable the duplication of materials when I duplicate my scene.

Note that if the answer is a script, I will need to be walked through how to use it as my Python skills are about a -52. :)

$\endgroup$
  • $\begingroup$ Did my answer help you, or are you looking for something else? If it was helpful, please mark it as answered, thanks. $\endgroup$ – Todd McIntosh Jul 21 '16 at 17:56
  • $\begingroup$ @ToddMcIntosh I'm sorry for being a terrible person, but I actually haven't tried it out yet. Is it ok if I mark it as accepted once I try it, or do you want the rep now? $\endgroup$ – Shady Puck Jul 21 '16 at 17:57
  • $\begingroup$ No, try it first, and let me know if you need help getting it to work. $\endgroup$ – Todd McIntosh Jul 21 '16 at 18:08
10
+50
$\begingroup$

You can run this script to replace all duplicated materials in your file. Just paste it into the Text editor and click the Run Script button.

It searches all objects, and then compares the first part of the material name (the part before the .001 suffix) with any materials named the same, and if a match is found replaces the object material with the matched material.

The idea would be to do a Full Scene copy and then run this script to remove all material duplicates.

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])

Before running the script, make sure your materials are named properly. Any material that ends with .001, .002 or 003, will be replaced by its "original version".

Credit for script goes to user liero on this BlenderArtist.org page

Ctrl + Shift + O finishes the job by reloading the file.

$\endgroup$
  • $\begingroup$ Worked like a charm. I do feel bad for making you wait so long, so I'm giving you a +50 bounty. Please accept my thanks. P.S. Just edited it with a little tip that I found handy. $\endgroup$ – Shady Puck Jul 22 '16 at 1:56
3
$\begingroup$

The following Add-on creates an empty scene, duplicates all objects and links them to the new one without duplicating the materials of the objects:

enter image description here Click to enlarge

Once it's enabled, hit Spacebar in 3D View and run 'Duplicate Scene'. Notice that it's a copy of the scene objects only, render and world settings are default.


custom-scene-duplicator.py

bl_info = {
    "name": "Duplicate Scene",
    "description": "",
    "author": "poor",
    "version": (0, 0, 1),
    "blender": (2, 70, 0),
    "location": "3D View > Spacebar > Duplicate Scene",
    "category": "3D View"
}

import bpy

def dupeObj(ob, scn):
    ob_copy = ob.copy()
    ob_data = ob.data.copy()
    ob_copy.data = ob_data
    scn.objects.link(ob_copy)
    scn.objects.active = ob_copy

class CustomDuplicateSceneOperator(bpy.types.Operator):
    """Duplicate all objects in the scene without material duplication"""
    bl_idname = "view3d.duplicate_scene"
    bl_label = "Duplicate Scene"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        # current scene
        orig_scene = context.scene.name
        bpy.ops.scene.new(type='NEW')

        # get the new scene
        new_scene = bpy.context.scene
        for ob in bpy.data.scenes[orig_scene].objects:
            dupeObj(ob, new_scene)

        self.report({'INFO'}, "Scene duplicated to {}".format(new_scene.name))
        return {'FINISHED'}

def register():
    bpy.utils.register_class(CustomDuplicateSceneOperator)

def unregister():
    bpy.utils.unregister_class(CustomDuplicateSceneOperator)

if __name__ == "__main__":
    register()

Install the Add-on via File > User Preferences > Add-ons > Install from File.

enter image description here

$\endgroup$
  • $\begingroup$ Ok, just downloaded and installed it. I copied the script into Aquamacs, a version of Emacs for Macs and saved it as a .py. Upon installing it and attempting to duplicate my scene, it worked okay. First, it switched to BI, so I turned it back to Cycles. Second, I lost a one-bone rig (Strech To Constraint), the rigged mesh, and the object that the bone was parented to. One separate thing that I think could be improved upon is I think the option should be added to the current Add Scene dropdown. I think you've got something really good here, it just needs some work to be perfect. $\endgroup$ – Shady Puck Jul 31 '16 at 18:21
  • $\begingroup$ @ShadyPuck Yep, needs more testing. I'll try to improve it as soon as I can. $\endgroup$ – p2or Aug 1 '16 at 9:51
  • $\begingroup$ Ok, let me know when it's done? Thanks! $\endgroup$ – Shady Puck Aug 1 '16 at 12:05
3
$\begingroup$

Wouldn't this be as simple as just using the New Scene > Link Objects New Scene > Link Object Data?

You can then select all objects and press U Make Single User > Object or Make Single User > Object and Data and you will have virtually duplicated your scene with all new objects with independent object data, but maintaining the same materials.

New scene

Only caveat is that if you have object instances inside the same scene their relationships will also be lost when making a single user.

You could work around this by selecting all objects with the same object data using Shift + L Select Linked > Object Data, making sure one of them is the active object, then making single user of the active object, then linking all of them back to the new one with Ctrl + L Link > Object Data

$\endgroup$
-1
$\begingroup$

A very simple tip to clean a scene from all its materials and orphan chunks, is to export in wavefront format (.obj). As a result, you will get two files. Obj file contains your objects with very few differences from blender except you loose modifiers. For example, if a subsurf modifier is active while you export, the object will be saved with subsurf applied. Arrays, wireframe or lattice are definitely applied to .obj objects.

The other file (.mtl) contains all materials (with their dependant textures). Erase or remame it and re_import .obj in a blank blender environment. All undesired chunks are cleaned from the new blend file.

It may be usefull when migrating a scene to Cycles Render or if your blend is full of orphan chunks (memory leaks) that didn't be erased when their parent reference been suppressed.

Hope it helps

$\endgroup$
  • 5
    $\begingroup$ This sounds like a horrible way to clean a blend file. Sure you get rid of unused materials, but it is terribly destructive to your models. I would never recommend using this method. $\endgroup$ – David Jul 13 '17 at 13:28
  • $\begingroup$ As it worked for me, I posted the answer. I had to remove modifiers before and recreate them manually in target file. Redo UV maps with same bitmaps. Topology is not destroyed while other methods transfer data-chunks regardless of how they're used. Once chunk is in the blend file, it looks impossible to remove (no garbage collection). $\endgroup$ – Lionel Hzg Jul 13 '17 at 15:31
  • $\begingroup$ I'm not professional in blender (i m developper) and I had errors from the beginning of my models (duplicate textured faces, grab shaders from popup instead of Ctrl-L) . My only option was to redo all from scratch. Obj export is definitly better ! $\endgroup$ – Lionel Hzg Jul 13 '17 at 15:38
  • 2
    $\begingroup$ You do not have to get defensive. (For the record I did not down vote your post) If that is the way you used, then ok. I was warning others to not do that because there are better ways. $\endgroup$ – David Jul 13 '17 at 18:53
  • $\begingroup$ Python script given is a huge help while object export is a python script too ! .obj is in text format you can browse with an editor and see what happens in blender database. It helps ! $\endgroup$ – Lionel Hzg Jul 13 '17 at 19:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.