User Tools

Site Tools


Sidebar

Dan's Wiki

DokuWiki Instructions (local) DokuWiki Manual
Site Checker (Orphans Wanted)

Edit Sidebar

blender:python:addonnotes:start

This is an old revision of the document!


Blender Python Addon Notes

Doing research to make a panel to control Baking Texture assignments.

Quick Tips

list(bpy.data.objects)
   # -> Lists objects array
type(bpy.data.objects)
<class 'bpy_prop_collection'>
   # -> Get the Python type
dir(bpy.data.objects)
   # -> Get the variables and methods on this class

Operators

The menu item: Help → Operator Cheat Sheet” gives a list of all operators and their default values in Python syntax, along with the generated docs. This is a good way to get an overview of all blender’s operators.

Operators don’t have return values as you might expect, instead they return a set() which is made up of: {'RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH'}. Common return values are {'FINISHED'} and {'CANCELLED'}.

Operator Property

https://docs.blender.org/api/blender_python_api_2_65_5/info_tutorial_addon.html#operator-property

Example:

# moved assignment from execute() to the body of the class...
total = bpy.props.IntProperty(name="Steps", default=2, min=1, max=100)
 
# and this is accessed on the class
# instance within the execute() function as...
self.total

How to Make Meshes with Python in Blender

from https://youtu.be/mljWBuj0Gho (Curtis Holt)

This is how to do it without using BMesh.

so = bpy.context.active_object
verts = so.data.vertices
edges = so.data.edges
faces = so.data.polygons
# coordinates:
# verts[i].co
for v in verts:
   print(v.co)
# edges[i].vertices[j]
for e in edges:
  # v is an index, 0 - N
  for v in e.vertices:
    print(v)

Creating a mesh

import bpy
 
verts = []
edges = []
faces = []
 
verts.append([ #index 0
  0.0, #x
  1.0, #y
  0.0 #z
])
verts.append([ #index 1
  1.0, #x
  0.0, #y
  0.0 #z
])
verts.append([ #index 2
  0.0, #x
  0.0, #y
  1.0 #z
])
verts.append([ #index 3
  -1.0, #x
  0.0, #y
  0.0 #z
])
 
# values are indexes
edges.append([0,1]) # but this isn't needed, because edges are added automatically
 
# values are index of vertexes
faces.append([0,1,2])
faces.append([2,0,3])
# The following works as long as there is a Collection called "Objects"
 
name = "New Object"
mesh = bpy.data.meshes.new(name)
obj = bpy.data.objects.new(name, mesh) # Object contains meta data, not just the mesh
col = bpy.data.collections.get("Objects")
col.objects.link(obj) # This will make the object actually display
bpy.context.view_layer.objects.active = obj # makes the object active (isn't working for me)
mesh.from_pydata(verts, edges, faces) # actually makes the mesh

Blender member variables

BL VariableExampleDescription
bl_contextuvThe context in which the panel belongs to
bl_idnameVIEW3D_PT_test_1Name of the object. If this is set, the panel gets a custom ID, otherwise it takes the name of the class used to define the panel. For example, if the class name is “OBJECT_PT_hello”, and bl_idname is not set by the script, then bl_idname = “OBJECT_PT_hello”
bl_labelPanel OneName of the object, shows up in a menu. The panel label, shows up in the panel header at the right of the triangle used to collapse the panel
bl_space_typeVIEW_3DThe space the panel will be used in. enum in [‘EMPTY’, ‘VIEW_3D’, ‘IMAGE_EDITOR’, ‘NODE_EDITOR’, ‘SEQUENCE_EDITOR’, ‘CLIP_EDITOR’, ‘DOPESHEET_EDITOR’, ‘GRAPH_EDITOR’, ‘NLA_EDITOR’, ‘TEXT_EDITOR’, ‘CONSOLE’, ‘INFO’, ‘TOPBAR’, ‘STATUSBAR’, ‘OUTLINER’, ‘PROPERTIES’, ‘FILE_BROWSER’, ‘SPREADSHEET’, ‘PREFERENCES’], default ‘EMPTY’
bl_region_typeUIenum in [‘WINDOW’, ‘HEADER’, ‘CHANNELS’, ‘TEMPORARY’, ‘UI’, ‘TOOLS’, ‘TOOL_PROPS’, ‘PREVIEW’, ‘HUD’, ‘NAVIGATION_BAR’, ‘EXECUTE’, ‘FOOTER’, ‘TOOL_HEADER’, ‘XR’], default ‘WINDOW’
bl_categoryToolThe category (tab) in which the panel will be displayed, when applicable. Leave blank if panel doesn't have tabs.
bl_optionsDEFAULT_CLOSEDOne of DEFAULT_CLOSED, HIDE_HEADER, INSTANCED, HEADER_LAYOUT_EXPAND - Formatting for this panel
bl_region_typeWINDOWenum in [‘WINDOW’, ‘HEADER’, ‘CHANNELS’, ‘TEMPORARY’, ‘UI’, ‘TOOLS’, ‘TOOL_PROPS’, ‘PREVIEW’, ‘HUD’, ‘NAVIGATION_BAR’, ‘EXECUTE’, ‘FOOTER’, ‘TOOL_HEADER’, ‘XR’], default ‘WINDOW’

register, unregister

To register a Python class, so that it can be used within Blender, this function needs to run when the Python file is loaded. This means it is at the same level as the class defintion, that is, not indented.

def register():
    bpy.utils.register_class(LayoutDemoPanel)

To unregister a Python class, so that it disappears from the menuing, you typically use something like this:

def unregister():
    bpy.utils.unregister_class(LayoutDemoPanel)

but when run from the Blender Python text editor, the class doesn't have any name space, so you have to find it first.

Note that “Panel” needs to be the type that this class is, one of Panel, UIList, Menu, Header, Operator, KeyingSetInfo, RenderEngine.

def unregister():
    myPanelClass = bpy.types.Panel.bl_rna_get_subclass_py("SCENE_PT_layout")
    bpy.utils.unregister_class(myPanelClass )

Python's automatic script variables

VariableDescription
__name__Contains “__main__” if run from the Blender text editor, otherwise, it contains the Python class which calls this

So we include this at the end of a Python script so that when running inside of Blender, it registers this class. Otherwise it doesn't need to, because the Script runner takes care of this. 2/15/2022

if __name__ == "__main__":
    register()
blender/python/addonnotes/start.1644972705.txt.gz · Last modified: 2022/02/16 00:51 by dwheele