TLDR; Import operators like import_scene.obj()
or import_scene.fbx()
don’t return any object name(s) nor a reference as you might expect, they only return {'FINISHED'}
.
>>> bpy.ops.import_scene.obj(filepath=</absolute/path/to/file.obj>)
{'FINISHED'}
Good news is all imported object(s) are selected right off the bat and we can get the reference(s) and name(s) after the import process either via bpy.context.object
for one object or bpy.context.selected_objects
in case the .obj
file consists of multiple objects.
import bpy
# Call the obj import operator and pass the absolute file path
bpy.ops.import_scene.obj(filepath="/home/p2or/Desktop/foo.obj")
# Get the context object, print the name and its reference
obj = bpy.context.object
print(obj.name, ":", obj)
# Get all imported objects and print their names
objs = bpy.context.selected_objects
print(", ".join(o.name for o in objs))
Alternatively you can create a set from all objects in the scene bpy.context.scene.objects
(t
), create another set (s
) right after the import process and subtract s
from t
, might take longer depending on how many objects coming in.
import bpy
# Create a set out of the objects in the current scene (unique by default)
objs = set(bpy.context.scene.objects)
bpy.ops.import_scene.obj(filepath="/home/p2or/Desktop/foo.obj")
# Substract all previous items from the current items and print their names
imported_objs = set(bpy.context.scene.objects) - objs
print(", ".join(o.name for o in imported_objs))
Basic demo
The following working example imports all meshes from the .obj
file given, prints their names for error handling, creates a new demo material and assigns the material to all slots or appends a new slot (if there is none) for all incoming objects.
import bpy
bpy.ops.import_scene.obj(filepath="/home/p2or/Desktop/foo.obj") # Linux
#bpy.ops.import_scene.obj(filepath="C:\\Users\\p2or\\Desktop\\foo.obj")# Windows
#bpy.ops.import_scene.obj(filepath="/Users/p2or/Desktop/foo.obj") # MacOS
# Get all objects (create a copy of the entire list)
objs = bpy.context.selected_objects[:]
# Generate or get the material
material_name = 'MaterialName'
mat = bpy.data.materials.get(material_name)
if mat is None:
mat = bpy.data.materials.new(material_name)
# Iterate through all imported objects
for obj in objs:
# Print the actual name and reference
# possibly modified since all names are unique
print(obj.name, obj)
# If there is no material slot append one with the (new) material
if not len(obj.data.materials):
obj.data.materials.append(mat)
# Assign the (newly created) material to all existing slots
for i in range(len(obj.data.materials)):
obj.data.materials[i] = mat
# Edit the material viewport properties
mat.diffuse_color = (0,1,0,1) # Viewport color
mat.roughness = 1.0 # Viewport roughness
# .../api/current/bpy.types.Material.html#bpy.types.Material.diffuse_color
# Edit the material and create all nodes from scratch
mat.use_nodes = True
nodes = mat.node_tree.nodes
nodes.clear()
node_principled = nodes.new(type='ShaderNodeBsdfPrincipled')
node_principled.inputs['Base Color'].default_value = (1,0,0,1) # Shader Base Color
node_principled.location = 0,0
node_output = nodes.new(type='ShaderNodeOutputMaterial')
node_output.location = 400,0
links = mat.node_tree.links
link = links.new(node_principled.outputs["BSDF"], node_output.inputs["Surface"])
# .../api/current/bpy.types.NodeTree.html#bpy.types.NodeTree.nodes
Related
For Blender 2.79 and earlier have a look into the revisions of this answer.