0
$\begingroup$

I've imported a model from the BodyParts3D database (http://lifesciencedb.jp/bp3d/) It's made up of a huge number of .obj files. These have a name based on the anatomical structure/organ: Blender scene hierarchy

My question is whether it's possible to use a Python script to go through the objects in the scene and;

  1. parent them together under an empty transform, according to a text string search
  2. add a material based on that text string

e.g. FJ2574_BP48954_FMA14964_Proximal part of ileum.obj

so any object with 'FMA14964' in its name would be parented under a transform named 'FMA14964', and be given the same material ('FMA14964_mat', or whatever).

For #2, I've found this 'How to assign a new material to an object in the scene from Python?' which I could probably work out how to tweak to do what I need, but I don't know how to iterate through the objects in the scene and do a a search based on a text string

I'm new to Python, but ok in C# and other programming languages. Fairly new to Blender (mostly I work in Unity) Any help would be very much appreciated!

$\endgroup$
2
$\begingroup$

Use string.split.

As you are already familiar with programming, and without a test file, will run thru an example. Use pythons String.split to split the name as is into a list using the underscore as a separator. If there are 4 members in the split etc..

import bpy
context = bpy.context 
scene = context.scene

def parent(name):
    ob = scene.objects.get(name)
    if not ob:
        ob = bpy.data.objects.new(name, None)
        scene.objects.link(ob)
    return ob

def material(name):
    ma = bpy.data.materials.get(name)
    if not ma:
        # add a new material as in link
        pass
    return ma

# iterate thru all obs in scene
for ob in scene.objects[:]:
    split = ob.name.split("_")
    if len(split) != 4:
        continue
    a, b, c, name = split
    ob.parent = parent(c)
    # add materials etc.
| improve this answer | |
$\endgroup$
  • $\begingroup$ Works wonderfully well, thanks for the prompt response. I couldn't work out what your material 'def' was doing, so I just rewrote the script slightly (added as answer to allow styling) $\endgroup$ – baroquedub Jun 7 '18 at 11:34
0
$\begingroup$

Working rewrite:

import bpy
context = bpy.context 
scene = context.scene

def parent(name):
    ob = scene.objects.get(name)
    if not ob:
        ob = bpy.data.objects.new(name, None)
        scene.objects.link(ob)
    return ob

# iterate thru all obs in scene
for ob in scene.objects[:]:
    split = ob.name.split("_")
    if len(split) != 4:
        continue
    a, b, c, name = split
    ob.parent = parent(c)
    # add materials etc.
    mat = bpy.data.materials.get(c+"_mat")
    if mat is None:
        # create material
        mat = bpy.data.materials.new(name=c+"_mat")

    # Assign it to object
    if ob.data.materials:
        # assign to 1st material slot
        ob.data.materials[0] = mat
    else:
        # no slots
        ob.data.materials.append(mat)
| improve this answer | |
$\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.