0
$\begingroup$

I was wondering if there is a way (or python script) to convert multiple identical meshes into instances? - where all other identical meshes are referring (instanced) to the first identical mesh e.g., BALUSTER.001.

The file was imported from ArchiCAD via FBX enter image description here

$\endgroup$
0
$\begingroup$

As long as the origins of the various objects are in correct relation to each object, there is a simple way to do this. Select all objects that are supposed to share the same mesh data, then - in the 3D View - hit Ctrl + L to open the link menu. From there, choose Object Data:

enter image description here

This will re-use the mesh data from the last selected object on all other instances. You can tell that they are instances in the mesh data tab of the outliner. The user count (number next to the data name) should have appeared and increased to reflect the number of meshes that re-use the data:

enter image description here

$\endgroup$
3
  • $\begingroup$ Thanks. This saves me a lot of time. $\endgroup$ – Simon Gaitara Mar 21 '20 at 15:28
  • $\begingroup$ I now also realize that a python script would save me "even more" time. Since the first identical mesh has a "- 001" suffix and the identical copies have "-001.001, -001.002, -001.003...suffix sequence. Any pointers on how to achieve this with a python script that checks the whole scene and links object data to each "-001" in a hierarchy? $\endgroup$ – Simon Gaitara Mar 21 '20 at 16:02
  • $\begingroup$ @SimonGaitara I have provided a second answer showing how to do this with Python. I do take a few assumptions and shortcuts, so be careful to save your imported scene before running this, and carefully check the result afterwards $\endgroup$ – aliasguru Mar 21 '20 at 19:35
0
$\begingroup$

An alternative answer to the same question using Python works as follows: I assume that the objects coming in are consistently named, and the restrictions of origin placement are the same as with the other answer I gave. With consistent naming I mean this:

my_obj_01 is supposed to share the data with my_obj_01.001, ..., my_obj_01.015, ...
my_obj_01 is NOT supposed to share the data with my_obj_02

If this is the case, then the following script will do what you request in one shot for the whole selection. So make sure to select the items you want to operate on first. If that's the whole scene, then so be it:

import bpy
import os

# purpose of this script is to link object data of objects by name
# the pattern used is that if an object name has duplicates following
# Blender's .001, .002, .003 syntax, the mesh data will be linked
# between them

# consider only mesh objects
objs = sorted([x for x in bpy.context.selected_editable_objects if x.type == 'MESH'], 
            key = lambda x: x.name)

# get a list of the names of the objects above, stripped from any .001, .002 etc
# this will create duplicate name entries enabling us to find the elements we want to link
obj_names_stripped = [os.path.splitext(x.name)[0] for x in objs]

# now iterate over the name list.
# Getting an enumerator here too to be able to index the object later on
for i, obj_name in enumerate(obj_names_stripped):

    # check for i=0 to skip the very first item     
    if i != 0:
        # check if the current item has the same name when stripped
        # than the previous item
        if obj_name == obj_names_stripped[i-1]: 
            # link the object datas of obj[i-1] and obj[i]
            objs[i].data = objs[i-1].data

A few notes

  • I am abusing the os module here to strip the .001, .002 etc that Blender adds when importing. However, be warned: I currently do NOT check if you have an object called my_obj.test. My script then would force such an object to share its mesh data with my_obj.other_test, as all I do is strip anything behind a dot.
  • I am using the trick to sort the list of objects you have selected using the sorted(list, key=function) method that Python provides. By doing so I only need to sequentially iterate over the whole object list once, and compare an item with the one before it. If their names are identical, I link the latter item to the one before, effectively daisy-chaining the mesh data of the first object found through to all copies
  • I use Pythons enumerate function to provide me a tuple of index and object from the name list, so I can access the mesh object from another list that has the same sorting as the name list
$\endgroup$

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.