Articles to read when Blender Python script code doesn't work in 2.80

Good morning Python! Everyone, are you modeling well today!

Speaking of which, when I tried to run Blender with a Python script, I was suffering from a mysterious error. As a result of struggling, it was found that the cause was ** API specification change **. You can think that most of the code currently published on the net (for ≒ 2.79 or earlier) ** does not work just by copying **.

So, for the currently released code, this will work with 2.80! I'm going to publish a modified version of it. After arranging the code before and after the change, I will explain in the form that the changed part is changed like this by referring to the corresponding reference. The key changes are about the same in every code, so it's probably useful for anyone who gets an error in another code.

The people who wrote the code are not bad at all, but there is no help for it because the specifications have changed. It's not that the evolving Blender is bad. If people are suffering when no one is bad ... I'll carry that sin.

First example

Blender x Python makes it easy 3DCG!

image.png

It is a script to create the above mesh.

code

original

2.79



import bpy
import math

#reset objects
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(True)

#world
bpy.context.scene.world.horizon_color=(0.0,0.0,0.0)

#plane_add
for i in range(0,100):
    bpy.ops.mesh.primitive_plane_add(radius = (i*1.1/100),location=(0,0,0),rotation=(math.pi*1/2,math.pi*i*8.2/360,math.pi*i*10/360))

for item in bpy.context.scene.objects:
    if item.type == 'MESH':
        bpy.context.scene.objects.active = bpy.data.objects[item.name]
        bpy.ops.object.modifier_add(type='WIREFRAME')
        bpy.context.object.modifiers['Wireframe'].thickness = 0.0025
        bpy.context.object.modifiers['Wireframe'].use_boundary = True

#lamp add
bpy.ops.object.lamp_add(type='HEMI',location=(0.0,0.0,2.0))

#camera add
bpy.ops.object.camera_add(location=(5.0,0.0,0.0))
bpy.data.objects['Camera'].rotation_euler = (math.pi*1/2, 0, math.pi*1/2)

#render
bpy.context.scene.render.resolution_x = 1000
bpy.context.scene.render.resolution_y = 1000
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.camera = bpy.context.object
bpy.context.scene.render.image_settings.file_format = 'PNG'
bpy.data.scenes["Scene"].render.filepath = "tmp/plane.png "
bpy.ops.render.render(write_still=True)

After change

2.80


import bpy
import math

#reset objects
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(True)

#plane_add
for i in range(0,100):
    bpy.ops.mesh.primitive_plane_add(size = (i*1.1/100),location=(0,0,0),rotation=(math.pi*1/2,math.pi*i*8.2/360,math.pi*i*10/360))

for item in bpy.context.scene.objects:
    if item.type == 'MESH':
        bpy.context.view_layer.objects.active = bpy.data.objects[item.name]
        bpy.ops.object.modifier_add(type='WIREFRAME')
        bpy.context.object.modifiers['Wireframe'].thickness = 0.0025
        bpy.context.object.modifiers['Wireframe'].use_boundary = True

#lamp add
bpy.ops.object.light_add(location=(0.0,0.0,2.0))

#camera add
bpy.ops.object.camera_add(location=(5.0,0.0,0.0))
bpy.data.objects['Camera'].rotation_euler = (math.pi*1/2, 0, math.pi*1/2)

#render
bpy.context.scene.render.resolution_x = 1000
bpy.context.scene.render.resolution_y = 1000
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.camera = bpy.context.object
bpy.context.scene.render.image_settings.file_format = 'PNG'
bpy.data.scenes["Scene"].render.filepath = "tmp/plane.png "
bpy.ops.render.render(write_still=True)

changes

2.79


    bpy.ops.mesh.primitive_plane_add(radius = (i*1.1/100),location=(0,0,0),rotation=(math.pi*1/2,math.pi*i*8.2/360,math.pi*i*10/360))

2.80


    bpy.ops.mesh.primitive_plane_add(size = (i*1.1/100),location=(0,0,0),rotation=(math.pi*1/2,math.pi*i*8.2/360,math.pi*i*10/360))

Added plane primitives. Radius indicating the scale is changed to size.

Applicable reference: https://docs.blender.org/api/current/bpy.ops.mesh.html?highlight=primitive%20plane#bpy.ops.mesh.primitive_plane_add

image.png

2.79


        bpy.context.scene.objects.active = bpy.data.objects[item.name]

2.80


        bpy.context.view_layer.objects.active = bpy.data.objects[item.name]

Select the active object. The part that was originally bpy.context.scene ~ should be changed to bpy.context.view_layer ~. I'm not sure exactly how to use it because the API of scene remains, but here is the reference [around here](https://docs.blender.org/api/current/bpy.types.Scene" There seems to be no choice but to read .html) and study.

2.79


bpy.ops.object.lamp_add(type='HEMI',location=(0.0,0.0,2.0))

2.80


bpy.ops.object.light_add(location=(0.0,0.0,2.0))

Addition of lamp. Renamed lamp to light. Also, the HEMI (hemisphere) type light has disappeared.

https://docs.blender.org/api/current/bpy.ops.object.html?highlight=light%20add#bpy.ops.object.light_add

image.png


#world
bpy.context.scene.world.horizon_color=(0.0,0.0,0.0)

No alternative API was found for this. In GUI

image.png

You can change it by operating here. There is an API called bpy.context.scene.world.color, but it doesn't change even if I specify this. This is out of reach. If you want to reproduce it, please change it manually. Excuse me…….

Second example

Introduction to blender python script_Part 01

image.png

It is a script that generates the above mesh without using primitives.

Source code

original

2.79


import bpy

#Remove default Cube
def delete_all():
    for item in bpy.context.scene.objects:
        bpy.context.scene.objects.unlink(item)

    for item in bpy.data.objects:
        bpy.data.objects.remove(item)

    for item in bpy.data.meshes:
        bpy.data.meshes.remove(item)

    for item in bpy.data.materials:
        bpy.data.materials.remove(item)

delete_all()

#Define vertex coordinates
coords=[
    (-1.0, -1.0, -1.0),
    ( 1.0, -1.0, -1.0),
    ( 1.0,  1.0, -1.0),
    (-1.0,  1.0, -1.0),
    ( 0.0,  0.0,  1.0)
]

#Define a face using this subscript
#Each face is defined by a sequence of four integers
#Triangular face must have the same first and fourth vertices
faces=[
    (2,1,0,3),
    (0,1,4,0),
    (1,2,4,1),
    (2,3,4,2),
    (3,0,4,3)
]

#Create a new mesh
me          = bpy.data.meshes.new("PyramidMesh")
#Create an object with a mesh
ob          = bpy.data.objects.new("Pyramid", me)
#Place the object at the 3D cursor position
ob.location = bpy.context.scene.cursor_location
#Link objects to scenes
bpy.context.scene.objects.link(ob)
#Fill the vertices, edges, and faces of the mesh
me.from_pydata(coords,[],faces)
#Update mesh with new data
me.update(calc_edges=True)

After change

2.80


import bpy

#Remove default Cube
def delete_all():
    for item in bpy.context.scene.objects:
        bpy.context.scene.collection.objects.unlink(item)

    for item in bpy.data.objects:
        bpy.data.objects.remove(item)

    for item in bpy.data.meshes:
        bpy.data.meshes.remove(item)

    for item in bpy.data.materials:
        bpy.data.materials.remove(item)

delete_all()

#Define vertex coordinates
coords=[
    (-1.0, -1.0, -1.0),
    ( 1.0, -1.0, -1.0),
    ( 1.0,  1.0, -1.0),
    (-1.0,  1.0, -1.0),
    ( 0.0,  0.0,  1.0)
]

#Define a face using this subscript
#Each face is defined by a sequence of four integers
#Triangular face must have the same first and fourth vertices
faces=[
    (2,1,0,3),
    (0,1,4,0),
    (1,2,4,1),
    (2,3,4,2),
    (3,0,4,3)
]

#Create a new mesh
me          = bpy.data.meshes.new("PyramidMesh")
#Create an object with a mesh
ob          = bpy.data.objects.new("Pyramid", me)
#Place the object at the 3D cursor position
ob.location = bpy.context.scene.cursor.location
#Link objects to scenes
bpy.context.scene.collection.objects.link(ob)
#Fill the vertices, edges, and faces of the mesh
me.from_pydata(coords,[],faces)
#Update mesh with new data
me.update(calc_edges=True)

changes

2.79


        bpy.context.scene.objects.unlink(item)

2.80


        bpy.context.scene.collection.objects.unlink(item)

It is a command about the object in the current scene, but since a hierarchy called collection has been added under scene, it is necessary to reflect it. There is also ʻobjects directly under scene, and if that is the case, an error will occur when link or ʻunlink the object, which is the first killing. ʻAttribute Error: Many people may have been cried by the error'bpy_prop_collection'object has no attribute'link'`.

2.79


ob.location = bpy.context.scene.cursor_location

2.80


ob.location = bpy.context.scene.cursor.location

Specify the cursor position. In 2.79 and below, there was an API called curosr_location, but in 2.80, it seems that there is a hierarchical structure with location under cursor.

Applicable reference: https://docs.blender.org/api/current/bpy.types.View3DCursor.html

image.png

2.79


bpy.context.scene.objects.link(ob)

2.80


bpy.context.scene.collection.objects.link(ob)

Same as the previous collection story.

Tips for finding a usable API

In this situation, there are too many changes and the information required is still small, so it is necessary to search for an API that can be used by yourself. At such times

image.png

Pressing the Ctrl + Space keys on Blender's Python console will bring up a list of candidate commands (if you type halfway, the candidates will be narrowed down accordingly), which may be useful. ..

Let's have a good Blender 2.80 life.

Recommended Posts

Articles to read when Blender Python script code doesn't work in 2.80
When matplotlib doesn't work with python2.7
[Subprocess] When you want to execute another Python program in Python code
Pin current directory to script directory in Python
Sample script to trap signals in Python
How to work with BigQuery in Python
To reference environment variables in Python in Blender
To work with timestamp stations in Python
Python script to convert latitude / longitude to mesh code
Personal notes to doc Python code in Sphinx
Materials to read when getting started with Python
Convert cubic mesh code to WKT in Python
I stumbled on the character code when converting CSV to JSON in Python
I want to write in Python! (1) Code format check
Read DXF in python
When send_keys doesn't work
Things to keep in mind when developing crawlers in Python
Template of python script to read the contents of the file
How to know the current directory in Python in Blender
Rewrite Python2 code to Python3 (2to3)
A memorandum when writing experimental code ~ Logging in python
A memorandum to run a python script in a bat file
Things to keep in mind when copying Python lists
Preparing to script control Rhino objects in Grasshopper / Python
I want to work with a robot in python.
Things to note when initializing a list in Python
What's in that variable (when running a Python script)
How to pass arguments when invoking python script from blender on the command line
How to exit when using Python in Terminal (Mac)
Deep nesting in Python makes it hard to read
Articles to see when installation for Python + OpenCV fails
[Work efficiency] How to change file names in Python
Things to keep in mind when processing strings in Python2
How to read csv containing only integers in Python
Things to keep in mind when processing strings in Python3
I want to do something in Python when I finish
[Python3] Code that can be used when you want to resize images in folder units
When I try to push with heroku, it doesn't work
[R] [Python] Memo to read multiple csv files in multiple zip files
Tips for coding short and easy to read in Python
What to do when "SSL: CERTIFICATE_VERIFY_FAILED _ssl.c: 1056" appears in Python
Things to keep in mind when using Python with AtCoder
Things to keep in mind when using cgi with python.
I want to be able to run Python in VS Code
[Python] Why pserve doesn't work
Login to website in Python
Read Namespace-specified XML in Python
Read Outlook emails in Python
Attention when os.mkdir in Python
Speech to speech in python [text to speech]
Generate QR code in Python
Blender Python API in Houdini (Python 3)
How to develop in Python
Character code learned in Python
Generate 8 * 8 (64) cubes in Blender Python
Convert python 3.x code to python 2.x
Read Fortran output in python
Post to Slack in Python
Write a script in Shell and Python to notify you in Slack when the process is finished
Things to watch out for when using default arguments in Python
How to not escape Japanese when dealing with json in python