2
$\begingroup$

Is there a way to do this?

For example, adding a subdivision modifier on the default cube then Alt+D to instance it. Going back to the first object, I'm unable to apply the modifiers.

I know that there are other ways such as making the object single user or simply deleting it but i was hoping there is a way to simply apply modifiers without doing the above.

$\endgroup$
3
  • $\begingroup$ Why not to Shift+D ... Since you want to Apply (make real) modifier, object is not instance anyway. Can you explain deeper case it comes usedull for you? Thank you $\endgroup$
    – vklidu
    Jan 15, 2022 at 7:56
  • $\begingroup$ you can't because Blender doesn't know what to do, as both the 2 objects share the same mesh is it also supposed to apply the modifier for the other instance? $\endgroup$
    – moonboots
    Jan 15, 2022 at 8:54
  • $\begingroup$ I am testing a way to do this now. It works with your exact case above blender.stackexchange.com/questions/262406/… $\endgroup$ May 2, 2022 at 15:04

1 Answer 1

0
$\begingroup$

This theoretically works for everything but geometry nodes

import bpy
import itertools 

#todo: displace (needs a lot of work with coordinates) 




def compareModifiers(original,test):
    
    #BOOLEAN,BUILD,NODES (geo nodes), MASK,VOLUME_TO_MESH
    modifierWhitelist = ("BEVEL" , "DECIMATE" , "SKIN", "SOLIDIFY","EDGE_SPLIT","REMESH","SKIN","SUBSURF",
        "TRIANGULATE","WELD","WIREFRAME","ARRAY","MIRROR","SCREW", "MULTIRES", "SMOOTH", "CORRECTIVE_SMOOTH",
        "LAPLACIANSMOOTH","SIMPLE_DEFORM") #starting with screw there are issues////
    #return all(mod_equality(m, test.modifiers[i])
    #            for i,m in enumerate(original.modifiers)) #check if the modifiers are the same
    for (mod,mod1) in zip(original.modifiers,test.modifiers):
        modType = getattr(mod,"type",True)
        mod1Type = getattr(mod1,"type",True)
        if not (modType==mod1Type):
            print("modtype issue")
            return False
        
        if modType == "MIRROR":
            if getattr(mod,"mirror_object",True) != None:
                print("mirror failure")
                return False
        
        if modType == "ARRAY":
            if getattr(mod,"use_object_offset",True) == True:
                print("array failure")
                return False
        if modType == "SCREW":
            if getattr(mod,"object",True) != None:
                print("screw failure")
                return False
            
        if modType == "SIMPLE_DEFORM":
            
            if getattr(mod,"origin",True) != None:
                print("simple deform failure")
                
                return False
        
        if modType not in modifierWhitelist:
            print(modType)
            print("unsupported modifiers used by objects. making them unique")
            return False
            #if modType == "
            
        for att in mod.bl_rna.properties.keys(): #we are in one of the whitelisted mods, making sure all attributes are the same
            #ignore name field
            #print(att)
            if att == "name":
                continue
            if att == "custom_profile":
                continue #TODO this is a bodge. The custom profiles are links to objects, not values, so more parsing is required
            #print(att)
            #print(str(att)+"  :  " + str(getattr(mod,att,True)) + "  :  " + str(getattr(mod1,att,True)) + "   :   " + str(getattr(mod,att,True) == getattr(mod1,att,True)))
            if att == "use_axis": #mirror modifier att fix
                print(tuple(getattr(mod,att,True)))
                print(tuple(getattr(mod1,att,True)))
                if (tuple(getattr(mod,att,True))) == tuple(getattr(mod1,att,True)):
                    continue
                else:
                    print("use axis failue")
                    return False
                
                
            if att == "use_bisect_axis": #mirror modifier att fix
                if (tuple(getattr(mod,att,True))) == tuple(getattr(mod1,att,True)):
                    continue
                else:
                    print("bisect axis failure")
                    return False
           
            if att == "use_bisect_flip_axis": #mirror modifier att fix
                if (tuple(getattr(mod,att,True))) == tuple(getattr(mod1,att,True)):
                    continue
                else:
                    print("flip axis failure")
                    return False
                
            if att == "limits": #simple deform fix
                if (tuple(getattr(mod,att,True))) == tuple(getattr(mod1,att,True)):
                    continue
                else:
                    print("limits failure")
                    return False
            
            if att == "lock": #simple deform fix
                if (tuple(getattr(mod,att,True))) == tuple(getattr(mod1,att,True)):
                    continue
                else:
                    print("lock failure")
                    return False
            
                        
            if getattr(mod,att,True) != getattr(mod1,att,True):
                print("mod attr equality failure:  " + str(att))
                return False
        
                        
            
    print("passed all tests")
    return True

objects = bpy.context.selected_objects
checkedObjects = objects
affectMeshesOutsideSelection = False

if affectMeshesOutsideSelection:
    print("affect outside meshes")
    checkedObjects = bpy.context.objects

while len(objects)>0:
    
    currentObject = objects[0]
    similarObjects = []
    similarObjects.append(currentObject)
    
    
    
    for o in checkedObjects:
        print("testing object   "+str(o))
        if o.data == currentObject.data:
            print("dataCheck")
            if compareModifiers(currentObject,o):
                print("modCheck")
                similarObjects.append(o)
                    
    currentObject.data = currentObject.data.copy()
    depsgraph = bpy.context.evaluated_depsgraph_get()
    object_eval = currentObject.evaluated_get(depsgraph)
    mesh_from_eval = bpy.data.meshes.new_from_object(object_eval)
    
    currentObject.data = mesh_from_eval
    currentObject.modifiers.clear()
    print("current object = " + str(currentObject))
    print("similar Objects = " + str(similarObjects))
    for o in similarObjects:
         o.modifiers.clear()
         o.data = currentObject.data
             
                        
    
    
    for o in similarObjects:
        try:
            objects.remove(o)
        except:
            #the only exception this can throw is that o is not in objects
            pass
    print("objects remaining  " + str(objects))
    
    
    
currentObject =[]
similarObjects = []
objects = []
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .