analitics

Pages

Saturday, June 4, 2022

Blender 3D and python scripting - part 011.

Today I show you how to create a branch using the Blender 3D A.P.I. together with the python programming language.
The source code seems complicated but if you follow the attached comments then you will understand how it works.
It contains two parts, one for creating the coordinates on the initial position of the branch (0,0,0) and one for creating the skin with different thicknesses.
Of note is the sorting of lists generated in the python language to get a nice increase as well as gradual thicknesses.
I've used the script several times to show you in the screenshot below some branches created with it.
Here is the source code used.
import bpy
import random
MinNubmer = -10
MaxNumber = 10

# Clean up the area , uncoment the next two row to keep
# branch after running the script
#bpy.ops.object.select_all(action="SELECT")
#bpy.ops.object.delete()

# Number of branches
branch = 6
# Create the verts array
verts = [(0,0,0)]
# Create the edges array
edges = [(0,0)]
# Create the faces array
faces = []

# Create the mesh for branch 
mesh = bpy.data.meshes.new("TreeMesh") 

# define random number for X and Y axis 
def RN():
    return  random.randint(MinNubmer, MaxNumber) / 20 

# define random number for positive Z axis
def RNZ():
    return  random.randint(10, 50) / 10  

# create a list of branch thicknesses
rand_list =[]
for i in range(1,branch):
    rand_list.append(RNZ()/30)
    # sort all reverse by thicknesses
    rand_list.sort(reverse=True)

# generate vertices list for drawing the branch
for i in range(1,branch):
    rand_list.append(RN())
    verts.append((rand_list[i-1] +0.1,rand_list[i-1]+0.1,RNZ()))
    edges.append((i-1,i))

# sort the list of vertices by last number witch is Z axis 
verts.sort(key=lambda x: x[2])

# create branch update and validate, see documentation
mesh.from_pydata(verts, edges, faces) 
mesh.update()
mesh.validate()

# Create object to hold the mesh branch 
obj = bpy.data.objects.new('Tree', mesh)

# ... and add it to the scene
scene = bpy.context.scene
scene.collection.objects.link(obj)

# add the skin modifier
obj.modifiers.new(name="SK", type="SKIN")
bpy.context.view_layer.objects.active = obj  
# get the skin vertices layers
skin_vertices = obj.data.skin_vertices
# get the layer
skin_layer = skin_vertices[0]

for i in range(1,branch):
    # assigns radius for each vertice to sized the branch 
    skin_layer.data[i-1].radius = (rand_list[i-1], rand_list[i-1]) #Indices 0 and 1 are the vertex indices
    skin_layer.data[i].radius = (rand_list[i-1],rand_list[i-1])

# set modes for user 
bpy.ops.object.mode_set(mode="EDIT", toggle=False)
bpy.ops.object.skin_root_mark()
bpy.ops.object.mode_set(mode="OBJECT", toggle=False)