8

I am trying to modify an object after importing it. This post is related to this question

import bpy
full_path_to_file = "C:\\Users\\xyz\\Documents\\test.obj"
bpy.ops.import_scene.obj(filepath=full_path_to_file)
# create the material
mat = bpy.data.materials.new('MaterialName')
mat.diffuse_color = (1.0,0.0,1.0)
mat.diffuse_shader = 'LAMBERT'
mat.diffuse_intensity = 1.0

# get the object
obj = bpy.data.objects['Cube']

# get the material
mat = bpy.data.materials['MaterialName']

# assign material to object
obj.data.materials.append(mat)

I wanted to add a material to the imported object but that is not happening. So I tried to scale it even that is not happening.

I realized that no operation is being performed on the imported objects. But the same operations are executing on the objects that are created (i.e. not imported).

Any help would be appreciated.

Ray Mairlot
  • 29,192
  • 11
  • 103
  • 125
Ross
  • 257
  • 1
  • 3
  • 7
  • You try to get an object named 'Cube', are you sure that is what you want? I think the imported object should be named 'test', like the .obj file. – maddin45 Feb 02 '15 at 17:47
  • yeah the name I entered is right. First I just import the object, check its name and then type in the rest of the code so that wrong name isn't a problem – Ross Feb 02 '15 at 17:51

1 Answers1

12

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.

p2or
  • 15,860
  • 10
  • 83
  • 143
  • 1
    Thanks a lot for your help. I had been working on this for a week but without luck. Actually on importing there was a default material. Thus appednding only created the material but did not apply it to the faces. 'obj.data.materials[0] = mat' helped to get the texture on the object :) – Ross Feb 03 '15 at 06:59