In this tutorial I will show you how you can add an extra branch to the existing one.
The source code was structured a bit with two createBranch and createNewBranch functions.
However, it is still in a raw structured format because such source code is aimed at using classes.
I did not solve the new branch size for the added vertex.
In the function that creates the new branch, the second parameter receives a number that represents the vertex from where the new edge will be created.
createNewBranch(obj_branch, 1)
In the source code we have the variable branch = 4, because the number of vertices starts in the list from 0 then argument 1 immediately means the next vertex from the first one in the list.
A random peak with close values is generated and an edge is added to link it to the previously selected one.
Here is the source code that adds a new branch.
import bpy
import random
# import bmesh
import bmesh
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 = 4
# Create the verts array
verts = [(0,0,0)]
# Create the edges array
edges = [(0,0)]
# Create the faces array
faces = []
# 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 = []
name_branch = "TreeMesh"
# define createBranch
def createBranch(branch, name_branch):
# Create the mesh for branch
mesh = bpy.data.meshes.new(name_branch)
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 with the new name for object
obj = bpy.data.objects.new(name_branch+'_Obj', mesh)
return obj
# use the createBranch
obj_branch = createBranch(branch, name_branch)
# ... and add it to the scene
scene = bpy.context.scene
scene.collection.objects.link(obj_branch)
# create a new branch
def createNewBranch(obj_branch, n):
bpy.ops.object.mode_set(mode="EDIT", toggle=False)
me = obj_branch.data
bm = bmesh.from_edit_mesh(me)
bm.select_mode = {'VERT'}
for i,v in enumerate(bm.verts):
# select only by the index of list
if i == n:
v.select = ( v.co.x > 0.0 )
v2 = v
else:
v.select = False
# flush and update view
v1 = bm.verts.new( (RN()+(v.co.x) + 0.1 , RN()+(v.co.y) + 0.1 , (v.co.z) - (v.co.z)/3) )
#v1 = bm.verts.new(1, 1, 3)
bm.edges.new((v1, v2))
# update
bm.select_flush_mode()
me.update()
#bmesh.update_edit_mesh(obj_branch.data)
# add the skin modifier - NOT FIXED FOR THE LAST BRANC ADDED
obj_branch.modifiers.new(name="SK", type="SKIN")
bpy.context.view_layer.objects.active = obj_branch
# get the skin vertices layers
skin_vertices = obj_branch.data.skin_vertices
# get the layer
skin_layer = skin_vertices[0]
for i in range(0,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()
createNewBranch(obj_branch, 1)
bpy.ops.object.mode_set(mode="OBJECT", toggle=False)