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 Answers 2

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.
$\endgroup$
1
  • $\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, 2018 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)
$\endgroup$

You must log in to answer this question.

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