Thursday, February 28, 2013

The code

This is a python code of 'Plant' generator Type01.


##########################################################################
#
#    'Plant' Generator Type 01 on Generative Modeling Project for Blender 2.66
#    Coded by Shigeto 'Shige' Maeda  2013-02-28
#    s.maeda@oud-japan.co.jp
#
##########################################################################

from bpy import *
import bpy
import math, mathutils, random

class GMP_Panel(bpy.types.Panel):
bl_label = "Plants Generator"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"

def draw(self, context):
layout = self.layout

scn = bpy.context.scene

row = layout.row()
# '''
row = row.column()
row.prop( scn, "Body_Amount" )

row = row.column()
row.label(text="Body parameter")

row = row.column()
row.prop( scn, "Body_Len" )
row = row.column()
row.prop( scn, "Body_Step_Dist" )
row = row.column()
row.prop( scn, "Body_Step_DegX" )
row = row.column()
row.prop( scn, "Body_Step_DegY" )
row = row.column()
row.prop( scn, "Body_Step_DegZ" )
row = row.column()
row.prop( scn, "Body_Phase_Oft" )
row = row.column()
row.prop( scn, "Body_Fat" )
row = row.column()
row.prop( scn, "Body_Freq" )
row = row.column()
row.prop( scn, "Body_DegX_Freq" )
row = row.column()
row.prop( scn, "Body_DegY_Freq" )

row = row.column()
row.label(text="Spine parameter")

row = row.column()
row.prop( scn, "Spine_face_Start" )
row = row.column()
row.prop( scn, "Spine_face_End" )
row = row.column()
row.prop( scn, "Spine_up_Start" )

row = row.column()
row.label(text="Seed parameter")

row = row.column()
row.prop( scn, "Seed_up_Start" )
row = row.column()
row.prop( scn, "Seed_up_End" )

row = row.column()
row.label(text="Root parameter")

row = row.column()
row.prop( scn, "Root_up_Start" )
row = row.column()
row.prop( scn, "Root_up_End" )

row = row.column()
row.label(text="Leaf parameter")

row = row.column()
row.prop( scn, "Leaf_up_Start" )

row = row.column()
row.label(text="Flower parameter")

row = row.column()
row.prop( scn, "Flower_Petal_Num" )

# '''
row = row.column()
row.label(text=" ")

row.operator( "bpt.generate_op" )

class GMP_Operator(bpy.types.Operator):
bl_idname = "bpt.generate_op"
bl_label = "Generate"

def execute(self, context):
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

Body_Amount = bpy.context.scene.Body_Amount #11
Body_Len = bpy.context.scene.Body_Len #1
Body_Step_Dist = bpy.context.scene.Body_Step_Dist #2
Body_Step_DegX = bpy.context.scene.Body_Step_DegX #3
Body_Step_DegY = bpy.context.scene.Body_Step_DegY #4
Body_Step_DegZ = bpy.context.scene.Body_Step_DegZ #5
Body_Phase_Oft = bpy.context.scene.Body_Phase_Oft #6
Body_Fat = bpy.context.scene.Body_Fat #7
Body_Freq = bpy.context.scene.Body_Freq #8
Body_DegX_Freq = bpy.context.scene.Body_DegX_Freq #9
Body_DegY_Freq = bpy.context.scene.Body_DegY_Freq #10

Spine_face_Start = bpy.context.scene.Spine_face_Start #12
Spine_face_End = bpy.context.scene.Spine_face_End #13
Spine_up_Start = bpy.context.scene.Spine_up_Start #14

Seed_up_Start = bpy.context.scene.Seed_up_Start #15
Seed_up_End = bpy.context.scene.Seed_up_End #16

Root_up_Start = bpy.context.scene.Root_up_Start #17
Root_up_End = bpy.context.scene.Root_up_End #18

Leaf_up_Start = bpy.context.scene.Leaf_up_Start #19

Flower_Petal_Num = bpy.context.scene.Flower_Petal_Num #20

for bodyNum in range(0, Body_Amount): #---------------------------------------< Number of objects
data = [bodyNum, Body_Len, Body_Step_Dist, Body_Step_DegX, Body_Step_DegY, Body_Step_DegZ, Body_Phase_Oft, Body_Fat, Body_Freq, Body_DegX_Freq, Body_DegY_Freq, Body_Amount, Spine_face_Start, Spine_face_End, Spine_up_Start, Seed_up_Start, Seed_up_End, Root_up_Start, Root_up_End, Leaf_up_Start, Flower_Petal_Num] 
generate(data)

bpy.ops.object.hide_view_clear()

#self.report( "INFO", "New Life was Generated!" )
return {'FINISHED'}

def register():
bpy.utils.register_class( GMP_Operator )
bpy.utils.register_class( GMP_Panel )

def unregister():
bpy.utils.register_class( GMP_Operator )
bpy.utils.register_class( GMP_Panel )

#------------------------------------------------------------------------------------ Main Code from here
# Extrude One Step ---------------------------------------->
def transStep(oneStep):
dZ = oneStep[0]
sX = oneStep[1]
sY = oneStep[2]
rA = oneStep[3]
aX = oneStep[4]
aY = oneStep[5]
aZ = oneStep[6]

selMode2FA()
bpy.ops.object.mode_set(mode='EDIT')
ob = bpy.context.object
# Scale control by face(area) size-->
context = bpy.context
if (context.active_object != None):
object = bpy.context.active_object
# if (object.type == "MESH"):
# faces = object.data.polygons
# vertices = object.data.vertices
# for f in faces:
# if (f.select) and f.area < 0.1 and sA < 0.2:
# sA = sA2 = 1.0
# ------------------------------------<

# Get the mesh
me = ob.data
# Loop through the faces to find the center
# for f in me.polygons:
# if f.select == True:
# center = f.center
# #area = f.area
# if center[0] > 0.0:
# rotDir = 1.0
# else:
# rotDir = -1.0
rotDir = 1
for p in me.polygons:
if p.select == True:
p_center = [0.0, 0.0, 0.0]
for v in p.vertices:
p_center[0] += me.vertices[v].co[0]        
# p_center[1] += me.vertices[v].co[1]
# p_center[2] += me.vertices[v].co[2]
p_center[0] /= len(p.vertices) # division by zero               
# p_center[1] /= len(p.vertices) # division by zero               
# p_center[2] /= len(p.vertices) # division by zero        
if p_center[0] > 0.0:
rotDir = 1.0
else:
rotDir = -1.0

bpy.ops.transform.shrink_fatten(value=dZ * sX, mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1.0, snap=False, snap_target='CLOSEST', snap_point=(0.0, 0.0, 0.0), snap_align=False, snap_normal=(0.0, 0.0, 0.0), release_confirm=False)
bpy.ops.transform.resize(value=(sX, sX, sX), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=0.0762767, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
bpy.ops.transform.rotate(value=(rA*rotDir), axis=(aX, aY, aZ), constraint_axis=(False, False, False), constraint_orientation='LOCAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=0.0762767, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

# TransformFaces(Multi Step) -------------------------------------------------------> except Leaf
def transformFaces(mltData):
vGroup = mltData[0] 
mainLevel = mltData[1] 
stepNum = mltData[2] 
stepDist = mltData[3] 
stepRot = mltData[4] 
startDeg = mltData[5] 
stepDeg = mltData[6] 
modLevel = mltData[7] 
modRate = mltData[8]
axis = mltData[9]
jointNum = mltData[10]

ob = bpy.context.object
# Make sure nothing is selected
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
selMode2FA()
# Select the vertex group
selPart(vGroup)

# Go into object mode so that we are sure we have the current list of faces 
bpy.ops.object.mode_set(mode='OBJECT')

# Make a nice list to keep the vertex groups in
groupList = []

# Now loop through all the faces
for i, f in enumerate(ob.data.polygons):

# If this face is selected
if ob.data.polygons[i].select == True:

# Create a new vertex group!
newGroup = ob.vertex_groups.new('mygroup')
groupList.append(newGroup)

# Get all the vertices in the current face and add them to the new group
for v in f.vertices:
newGroup.add([v], 1.0, 'REPLACE')

# Now we loop through the groups and do what we want.
for g in groupList:

# Make sure nothing is selected
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')

# Make the group in our list the active one
ob.vertex_groups.active_index = g.index

# Select all the verts in the active group
bpy.ops.object.vertex_group_select()

bpy.ops.object.vertex_group_remove(all=False)

# AND NOW WE CAN DO OUR STUFF... little test example follows
t = startDeg
oldValue = 1.0
oldValue2 = 1.0
# Shape
j = 0
if stepNum == 99:
RandStepNum = random.randint(6, 20)
else:
RandStepNum = stepNum

#dirFace = -1**(random.randint(0, 2))
dirFace = random.uniform(0.3, 1.0)**random.randint(0, 2)
for i in range(RandStepNum):
     
bpy.ops.mesh.extrude_region(mirror=False)

# An added trick... remove the extruded face from all vertex groups after the first extrusion (i == 0)
# This way it can't get extruded again
# Because the edge of the first face can be part of multiple groups
if not i:
bpy.ops.object.vertex_group_remove_from(all=True)

bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')

newValue = (math.sin(math.radians(t)+math.sin(math.radians(t/2.3)))+2.0)*mainLevel
#newValue2 = (math.sin(math.radians(t*1.2)+math.sin(math.radians(t/1.3)))+2.0)*mainLevel
newRatio = newValue/oldValue
#newRatio2 = newValue2/oldValue2

# Get the mesh
me = ob.data
# Loop through the faces to find the center
area = 1
for p in me.polygons:
if p.select == True and vGroup != 'body' and vGroup != 'spine' and vGroup != 'leg':
area = math.sqrt(p.area) * 3

dZ = stepDist * area
sX = newRatio
sY = newRatio
rA = modLevel*math.sin(math.radians(t*modRate))*(-stepRot/10)*dirFace
aX = axis[0]
aY = axis[1]
aZ = axis[2]

snglData = [dZ, sX, sY, rA, aX, aY, aZ]
transStep(snglData)

if jointNum != 0:
j = j+1
if j == jointNum:
bpy.ops.mesh.extrude_region(mirror=False)
snglData = [-0.01, 0.6, 0.6, 0, aX, aY, aZ]
transStep(snglData) # <-------------0
bpy.ops.mesh.extrude_region(mirror=False)
snglData = [-0.01, 1.66, 1.66, 0, aX, aY, aZ]
transStep(snglData) # <-------------0
j = 0
t = t + stepDeg
oldValue = newValue
#oldValue2 = newValue2

# transformFaces!(END) --------------------------------------------------<

# TransformLeaf(Multi Step) -------------------------------------------------------> Leaf
def transformLeaf(mltData):
vGroup = mltData[0] 
mainLevel = mltData[1] 
stepNum = mltData[2] 
stepDist = mltData[3] 
stepRot = mltData[4] 
startDeg = mltData[5] 
stepDeg = mltData[6] 
modLevel = mltData[7] 
modRate = mltData[8]
axis = mltData[9]
jointNum = mltData[10]

ob = bpy.context.object
# Make sure nothing is selected
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
selMode2FA()
# Select the vertex group
selPart(vGroup)

# Go into object mode so that we are sure we have the current list of faces 
bpy.ops.object.mode_set(mode='OBJECT')

# Make a nice list to keep the vertex groups in
groupList = []

# Now loop through all the faces
for i, f in enumerate(ob.data.polygons):

# If this face is selected
if ob.data.polygons[i].select == True:

# Create a new vertex group!
newGroup = ob.vertex_groups.new('mygroup')
groupList.append(newGroup)

# Get all the vertices in the current face and add them to the new group
for v in f.vertices:
newGroup.add([v], 1.0, 'REPLACE')

# Now we loop through the groups and do what we want.
for g in groupList:

# Make sure nothing is selected
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')

# Make the group in our list the active one
ob.vertex_groups.active_index = g.index

# Select all the verts in the active group
bpy.ops.object.vertex_group_select()

bpy.ops.object.vertex_group_remove(all=False)

# AND NOW WE CAN DO OUR STUFF... little test example follows
t = startDeg
oldValue = 1.0
oldValue2 = 1.0
# Shape
j = 0
if stepNum == 99:
RandStepNum = random.randint(6, 20)
else:
RandStepNum = stepNum

#dirFace = -1**(random.randint(0, 2))
dirFace = random.uniform(0.3, 1.0)**random.randint(0, 2)
oneStepDeg = 270/RandStepNum
for i in range(RandStepNum):
     
bpy.ops.mesh.extrude_region(mirror=False)

# An added trick... remove the extruded face from all vertex groups after the first extrusion (i == 0)
# This way it can't get extruded again
# Because the edge of the first face can be part of multiple groups
if not i:
bpy.ops.object.vertex_group_remove_from(all=True)

bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')

#newValue = (math.sin(math.radians(t)+math.sin(math.radians(t/2.3)))+2.0)*mainLevel
#newValue2 = (math.sin(math.radians(t*1.2)+math.sin(math.radians(t/1.3)))+2.0)*mainLevel
newValue = (math.sin(math.radians(i*oneStepDeg))+1)*mainLevel
#newValue2 = (math.sin(math.radians(i*oneStepDeg))+1)*mainLevel*leafWidth
newRatio = newValue/oldValue
#newRatio2 = newValue2/oldValue2

# Get the mesh
me = ob.data
# Loop through the faces to find the center
area = 1
for p in me.polygons:
if p.select == True and vGroup != 'body' and vGroup != 'spine' and vGroup != 'leg':
area = math.sqrt(p.area) * 3

dZ = stepDist * area
sX = newRatio
sY = newRatio
rA = modLevel*math.sin(math.radians(t*modRate))*(-stepRot/10)*dirFace
aX = axis[0]
aY = axis[1]
aZ = axis[2]

#if i==1:
# sX *= leafWidth
snglData = [dZ, sX, sY, rA, aX, aY, aZ]
transStep(snglData)

if jointNum != 0:
j = j+1
if j == jointNum:
bpy.ops.mesh.extrude_region(mirror=False)
snglData = [-0.01, 0.6, 0.6, 0, aX, aY, aZ]
transStep(snglData) # <-------------0
bpy.ops.mesh.extrude_region(mirror=False)
snglData = [-0.01, 1.66, 1.66, 0, aX, aY, aZ]
transStep(snglData) # <-------------0
j = 0
t = t + stepDeg
oldValue = newValue
#oldValue2 = newValue2

# transformLeaf!(END) --------------------------------------------------<

#SelectMode->FACE
def selMode2FA():
ob = bpy.context.object
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type='FACE')
bpy.ops.object.mode_set(mode='OBJECT')

#SelectMode->VERT
def selMode2VT():
ob = bpy.context.object
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type='VERT')
bpy.ops.object.mode_set(mode='OBJECT')

# select faces from Groups --------------------------------------------->
def selPart(vGroup):
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.vertex_group_set_active(group=vGroup)
bpy.ops.object.vertex_group_select()
bpy.ops.object.vertex_group_remove(all=False)
# select faces from Groups (END)----------------------------------------<
# select faces from Groups NO REMOVE--------------------------------------------->
def selPartNoRemove(vGroup):
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.vertex_group_set_active(group=vGroup)
bpy.ops.object.vertex_group_select()
# select faces from Groups NO REMOVE(END)----------------------------------------<
# assignFacesAngle--------------------------------------------->
def assignFacesAngle(assignFace):
vGroup = assignFace[0]
fAngleMin = assignFace[1]
fAngleMax = assignFace[2]
zMin = assignFace[3]
zMax = assignFace[4]

ob = bpy.context.object
#bpy.ops.object.mode_set(mode='EDIT')
#bpy.ops.object.vertex_group_remove(all=True)
newGroup = ob.vertex_groups.new(vGroup)
bpy.ops.object.mode_set(mode='OBJECT')

up = mathutils.Vector((0.0,0.0,1.0))

# Lets loop through all the faces in the mesh
me = ob.data
for p in me.polygons:
p_center = [0.0, 0.0, 0.0]
for v in p.vertices:
p_center[0] += me.vertices[v].co[0]        
p_center[1] += me.vertices[v].co[1]
p_center[2] += me.vertices[v].co[2]
p_center[0] /= len(p.vertices) # division by zero               
p_center[1] /= len(p.vertices) # division by zero               
p_center[2] /= len(p.vertices) # division by zero      

# If the angle between up and the face's normal (direction) is smaller than 45... 
# The face must be pointing up
# To compare the angle we need 45 degrees in radians, not in degrees!
# Math with angles is usually all in radians
# if f.normal.angle(up) > math.radians(fAngleMin) and f.normal.angle(up) < math.radians(fAngleMax) and f.center[1] > yMin and f.center[1] < yMax :
if p.normal.angle(up) > math.radians(fAngleMin) and p.normal.angle(up) < math.radians(fAngleMax) and p_center[2] > zMin and p_center[2] < zMax :
# Set select to true
p.select = True
else:
p.select = False

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.vertex_group_set_active(group=vGroup)
bpy.ops.object.vertex_group_assign(new=False)
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
# assignFacesAngle(END)--------------------------------------<

# assignRandomSelect------------------------------------------>
def assignRandomSelect(assignRandom):
vGroup = assignRandom[0]
randPer = assignRandom[1]
zMin = assignRandom[2]
zMax = assignRandom[3]

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_random(percent=randPer, extend=False)
bpy.ops.object.mode_set(mode='OBJECT')
ob = bpy.context.object
newGroup = ob.vertex_groups.new(vGroup)
bpy.ops.object.vertex_group_set_active(group=vGroup)
bpy.ops.object.mode_set(mode='EDIT')

me = ob.data
for p in me.polygons:
p_center = [0.0, 0.0, 0.0]
for v in p.vertices:
p_center[0] += me.vertices[v].co[0]        
p_center[1] += me.vertices[v].co[1]
p_center[2] += me.vertices[v].co[2]
p_center[0] /= len(p.vertices) # division by zero               
p_center[1] /= len(p.vertices) # division by zero               
p_center[2] /= len(p.vertices) # division by zero

if p_center[2] > zMin and p_center[2] < zMax :
# Set select to true
p.select = True
else:
p.select = False

bpy.ops.object.vertex_group_assign(new=False)
# assignRandamSelect(END)-------------------------------------<

# removeVertexGroupFrom-------------------------------------->
def removeVGroupFrom(removeAfromB):
vGroupA = removeAfromB[0]
vGroupB = removeAfromB[1]

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_set_active(group=vGroupA)
bpy.ops.object.vertex_group_select()

bpy.ops.object.vertex_group_set_active(group=vGroupB)
bpy.ops.object.vertex_group_deselect()

bpy.ops.object.vertex_group_set_active(group=vGroupA)
bpy.ops.object.vertex_group_remove(all=False)
ob = bpy.context.object
newGroup = ob.vertex_groups.new(vGroupA)
bpy.ops.object.vertex_group_set_active(group=vGroupA)
bpy.ops.object.vertex_group_assign(new=False)

# removeVertexGroupFrom(END)---------------------------------<

# deselectAllMesh------------------------------------------>
def deselectAllMesh():
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
# deselectAllMesh(END)-------------------------------------<

# listOfFacePosAndNormal----------------------------------->
def listOfFacePosAndNormal(Group):
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
ob = bpy.context.object
me = ob.data
vGroup = Group
selPartNoRemove(vGroup)

# Number of Selected Faces
# Go into object mode so that we are sure we have the current list of faces 
bpy.ops.object.mode_set(mode='OBJECT')

# Make a nice list to keep the vertex groups in
faceList = []
faceNum = 0
# Now loop through all the faces
for i, f in enumerate(ob.data.polygons):
# If this face is selected
if f.select == True:
# Count the faces
faceNum += 1

faceList.append(faceNum)
for i, f in enumerate(ob.data.polygons):
if f.select == True:
f_center = [0.0, 0.0, 0.0]
for v in f.vertices:
f_center[0] += me.vertices[v].co[0]        
f_center[1] += me.vertices[v].co[1]
f_center[2] += me.vertices[v].co[2]
f_center[0] /= len(f.vertices) # division by zero               
f_center[1] /= len(f.vertices) # division by zero               
f_center[2] /= len(f.vertices) # division by zero

faceList.append(f_center[0])
faceList.append(f_center[1])
faceList.append(f_center[2])
faceList.append(f.normal[0])
faceList.append(f.normal[1])
faceList.append(f.normal[2])

deselectAllMesh()
return faceList

# listOfFacePosAndNormal(END)------------------------------<

#bodySpine()
def bodySpine():
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')

bpy.ops.object.mode_set(mode='OBJECT')
selMode2FA()

sp1 = random.uniform(0, 0)
sp2 = random.uniform(120, 240)
sp3 = random.uniform(0, 5)
sp4 = random.uniform(5, 10)
assignList = ['spine', sp1, sp1 + sp2, sp3, sp3 + sp4]

assignFacesAngle(assignList)

transformList = ['spine', 0.1, 2, -0.2, 0, 0, 0, 0, 0, [-2.22045e-16, -1, -0], 0]
transformFaces(transformList)
bpy.ops.object.mode_set(mode='OBJECT')

#makeFlower----------------------------------------------->
def makeFlower(faceList, obX, obY, flower_petal_num):
Num = faceList[0]
for i in range(Num):
cX = faceList[i * 6 + 1]
cY = faceList[i * 6 + 2]
cZ = faceList[i * 6 + 3]
norX = faceList[i * 6 + 4]
norY = faceList[i * 6 + 5]
norZ = faceList[i * 6 + 6]
petalNum = flower_petal_num
#bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(obX+cX, obY+cY, cZ), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
bpy.ops.mesh.primitive_cone_add(vertices=petalNum, radius1=0.5, radius2=0.38, depth=0.2, end_fill_type='TRIFAN', view_align=False, enter_editmode=False, location=(0, 0, 0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
vGroup = 'middle'
flowerList = [vGroup, 20, 150, -1, 1]
assignFacesAngle(flowerList)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
selPartNoRemove(vGroup)
bpy.ops.mesh.extrude_faces_move(MESH_OT_extrude_faces_indiv={"mirror":False}, TRANSFORM_OT_shrink_fatten={"value":-0.1, "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
vGroup = 'hanabira'
ob = bpy.context.object
newGroup = ob.vertex_groups.new(vGroup)
bpy.ops.object.vertex_group_set_active(group=vGroup)
bpy.ops.object.vertex_group_assign(new=False)
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
vGroup = 'inside'
flowerList = [vGroup, -10, 20, 0, 1]
assignFacesAngle(flowerList)
vGroup = 'outside'
flowerList = [vGroup, 170, 200, -1, 0]
assignFacesAngle(flowerList)
vGroup = 'hanabira'
selPartNoRemove(vGroup)
transformList = [vGroup, 1.0, 7, -0.3, -5.0, 60.0, 10.0, 1.0, 1.0, [-2.22045e-16, -1, -0], 0]
transformLeaf(transformList)
deselectAllMesh()
vGroup = 'inside'
selPartNoRemove(vGroup)
transformList = [vGroup, 0.4, 4, -0.25, -5.0, 0.0, 10.0, 1.0, 1.0, [-2.22045e-16, -1, -0], 0]
transformLeaf(transformList)
deselectAllMesh()
vGroup = 'outside'
selPartNoRemove(vGroup)
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, -0.3), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
bpy.ops.transform.resize(value=(0.6, 0.6, 0.6), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, -0.3), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
bpy.ops.transform.resize(value=(0.8, 0.8, 0.8), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
for i in range(3):
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
bpy.ops.transform.translate(value=(random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5), -0.8), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
rS = random.uniform(1.0, 1.2)
bpy.ops.transform.resize(value=(rS, rS, rS), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, -0.5), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
bpy.ops.transform.resize(value=(1.3, 1.3, 1.3), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, -0.2), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
bpy.ops.transform.resize(value=(0.2, 0.2, 0.2), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)

bpy.ops.view3d.snap_cursor_to_selected()
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, -0.1), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
bpy.ops.transform.resize(value=(0.5, 0.5, 0.5), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
bpy.ops.object.mode_set(mode='OBJECT')

ob = bpy.context.object
ob.location[0] = obX+cX
ob.location[1] = obY+cY
ob.location[2] = cZ

bpy.ops.transform.rotate(value=1.5, axis=(norX, norY, norZ), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

#makeFlower(END)------------------------------------------<

# Generate Object!!! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
def generate(data):
bodyNum = data[0]
bodyLen = data[1]
bodyStepDist = data[2]
bodyStepDegX = data[3]
bodyStepDegY = data[4]
bodyStepDegZ = data[5]
bodyPhaseOft = data[6]
bodyFat = data[7]
bodyFreq = data[8]
bodyDegXFreq = data[9]
bodyDegYFreq = data[10]
body_Amount = data[11]
spine_face_start = data[12]
spine_face_end = data[13]
spine_up_start = data[14]
seed_up_start = data[15]
seed_up_end = data[16]
root_up_start = data[17]
root_up_end = data[18]
leaf_up_start = data[19]
flower_petal_num = data[20]

if body_Amount < 5:
totalRow = body_Amount
else:
totalRow = 5
totalCol = (int)(body_Amount / totalRow)
objGap = 15
if body_Amount < totalRow:
obX = (bodyNum - (body_Amount - 1)/2) * objGap
else:
obX = (bodyNum % totalRow) * objGap - objGap * ((totalRow - 1) / 2)

obY = (int)(bodyNum / totalRow) * objGap - objGap * ((totalCol) / 2)

#obY = (int)(bodyNum / 5) * objGap - objGap * 2
randX = random.uniform(-30, 30)
randY = random.uniform(-30, 30)

bpy.ops.mesh.primitive_plane_add(view_align=False, enter_editmode=False, location=(obX, obY, 0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

selMode2FA()
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.transform.resize(value=(0.2 * bodyFat, 0.2 * bodyFat, 0.2 * bodyFat), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, bodyStepDist), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})

oldResNum = 1.0
t = 0.0
for i in range(bodyLen):
bpy.ops.mesh.extrude_faces_move(MESH_OT_extrude_faces_indiv={"mirror":False}, TRANSFORM_OT_shrink_fatten={"value":-bodyStepDist, "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
#bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(0, 0, bodyStepDist), "constraint_axis":(False, False, True), "constraint_orientation":'NORMAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "texture_space":False, "release_confirm":False})
degX = math.cos(math.radians(t * bodyDegXFreq) + randX) * bodyStepDegX
bpy.ops.transform.rotate(value=math.radians(degX), axis=(1, 0, 0), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)
degY = math.cos(math.radians(t * bodyDegYFreq) + randY) * bodyStepDegY
bpy.ops.transform.rotate(value=math.radians(degY), axis=(0, 1, 0), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)
bpy.ops.transform.rotate(value=math.radians(bodyStepDegZ), axis=(0, 0, 1), constraint_axis=(False, False, False), constraint_orientation='NORMAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

newResNum = (0.8 * math.sin(math.radians(t * bodyFreq + bodyPhaseOft)) + 1)/oldResNum

bpy.ops.transform.resize(value=(newResNum, newResNum, newResNum), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)

oldResNum = newResNum
t += 1.0

#---------------------------------------Flower on top
# vGroup = 'flower'
# ob = bpy.context.object
# bpy.ops.mesh.select_all(action='INVERT')
# bpy.ops.mesh.hide(unselected=False)
#bpy.ops.mesh.select_all(action='SELECT')
#bpy.ops.mesh.select_random(percent=50, extend=False)
# newGroup = ob.vertex_groups.new(vGroup)
#bpy.ops.object.vertex_group_set_active(group=vGroup)
#bpy.ops.object.vertex_group_assign(new=False)
#bpy.ops.mesh.reveal()
# bpy.ops.mesh.select_all(action='DESELECT')

bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.modifier_add(type='SUBSURF')
object = bpy.context.active_object
object.modifiers['Subsurf'].levels = 1

bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Subsurf")
# bpy.ops.object.mode_set(mode='EDIT')
# bpy.ops.mesh.select_random(percent=50, extend=False)
# bpy.ops.object.vertex_group_set_active(group=vGroup)
# bpy.ops.object.vertex_group_assign(new=False)
# bpy.ops.mesh.reveal()

# bpy.ops.mesh.select_all(action='DESELECT')
  #bpy.ops.object.mode_set(mode='OBJECT')
# faceList = listOfFacePosAndNormal(vGroup)

#----- Select Spine area
vGroup = 'spine'
#fromNum = random.uniform(0.0, 3.0)
toNum = random.uniform(4, bodyLen*bodyStepDist)
#assignList = [vGroup, 0, 150, 0, toNum]
assignList = [vGroup, spine_face_start, spine_face_end, spine_up_start, toNum]
assignFacesAngle(assignList)
#----- Select Seed
vGroup = 'seed'
randPer = random.uniform(10.0, 50.0)
#assignList = [vGroup, randPer, 1.0, 3.0]
assignList = [vGroup, randPer, seed_up_start, seed_up_end]
assignRandomSelect(assignList)
#----- Select Root area
vGroup = 'root'
#assignList = [vGroup, 100, 225, 0, 2.0]
assignList = [vGroup, 100, 225, root_up_start, root_up_end]
assignFacesAngle(assignList)
#----- Select leaf
vGroup = 'leaf'
randPer = random.uniform(12.5, 75.5)
#assignList = [vGroup, randPer, 7.0, bodyLen*bodyStepDist]
assignList = [vGroup, randPer, leaf_up_start, bodyLen*bodyStepDist]
assignRandomSelect(assignList)
#----- Select Flower area
vGroup = 'flower'
randPer = random.uniform(50.0, 80.0)
assignList = [vGroup, randPer, bodyLen*bodyStepDist*0.5 , bodyLen*bodyStepDist]
assignRandomSelect(assignList)

# bpy.ops.object.mode_set(mode='OBJECT')
# space = context.space_data
# space.pivot_point = "INDIVIDUAL_ORIGINS"

# vGroup = 'random' 
# mainLevel = 0.3
# stepNum = bodyLen 
# stepDist = -0.5 
# stepRot = 5.0 
# startDeg = 0.0 
# stepDeg = 5.0 
# modLevel = 5.0 
# modRate = 1.0
# axis = [1, 1, 0]
# jointNum = 0
# multistepData = [vGroup, mainLevel, stepNum, stepDist, stepRot, startDeg, stepDeg, modLevel, modRate, axis, jointNum, leafWidth]

removeAfromB = ['flower','leaf']
removeVGroupFrom(removeAfromB)
removeAfromB = ['flower','spine']
removeVGroupFrom(removeAfromB)
removeAfromB = ['flower','root']
# removeVGroupFrom(removeAfromB)
removeAfromB = ['flower','seed']
# removeVGroupFrom(removeAfromB)
vGroup = 'flower'
faceList = listOfFacePosAndNormal(vGroup)

removeAfromB = ['leaf','spine']
removeVGroupFrom(removeAfromB)

removeAfromB = ['spine','seed']
removeVGroupFrom(removeAfromB)

removeAfromB = ['spine','root']
removeVGroupFrom(removeAfromB)

removeAfromB = ['seed','leaf']
removeVGroupFrom(removeAfromB)

transformList = ['flower', 0.2, 2, -0.1, 0, 0, 0, 0, 0, [-2.22045e-16, -1, -0], 0]
transformFaces(transformList)

transformList = ['spine', 0.1, 2, -0.2, 0, 0, 0, 0, 0, [-2.22045e-16, -1, -0], 0]
transformFaces(transformList)

transformList = ['seed', 0.4, 6, -0.15, 0, 270, 95, 0, 0, [-2.22045e-16, -1, -0], 0]
transformFaces(transformList)

transformList = ['root', 0.2, 99, -0.3, 5.0, 60.0, 10.0, 1.0, 1.0, [-2.22045e-16, 0, -1], 0]
transformFaces(transformList)

transformList = ['leaf', 0.3, 12, -0.25, -5.0, 60.0, 20.0, 1.0, 1.0, [-2.22045e-16, -1, -0], 0]
transformLeaf(transformList)

bpy.ops.object.mode_set(mode='OBJECT')
makeFlower(faceList, obX, obY, flower_petal_num)

#bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.join()
#bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.modifier_add(type='SUBSURF')
object = bpy.context.active_object
object.modifiers['Subsurf'].levels = 2
bpy.ops.object.hide_view_set(unselected=False)

#------------------------------------------------------------------------------------ Main Code to here

if __name__ == '__main__':
# '''
bpy.types.Scene.Body_Amount = bpy.props.IntProperty(name="Body_Amount", default = 1, min = 1, max = 15, description = "Body Amount")

bpy.types.Scene.Body_Len = bpy.props.IntProperty(name="Body_Len", default = 9, min = 2, max = 12, description = "Body Len")
bpy.types.Scene.Body_Step_Dist = bpy.props.FloatProperty(name="Body_Step_Dist", default = 1.5, min = 1.0, max = 5.0, description = "Body Step Dist")
bpy.types.Scene.Body_Step_DegX = bpy.props.FloatProperty(name="Body_Step_DegX", default = 9.5, min = -30, max = 30, description = "Body Step DegX")
bpy.types.Scene.Body_Step_DegY = bpy.props.FloatProperty(name="Body_Step_DegY", default = 12.6, min = -30, max = 30, description = "Body Step DegY")
bpy.types.Scene.Body_Step_DegZ = bpy.props.FloatProperty(name="Body_Step_DegZ", default = 16.5, min = -30, max = 30, description = "Body Step DegZ")
bpy.types.Scene.Body_Phase_Oft = bpy.props.FloatProperty(name="Body_Phase_Oft", default = -43.3, min = -180, max = 180, description = "Body Phase Oft")
bpy.types.Scene.Body_Fat = bpy.props.FloatProperty(name="Body_Fat", default = 4.5, min = 1.0, max = 15.0, description = "Body Fat")
bpy.types.Scene.Body_Freq = bpy.props.FloatProperty(name="Body_Freq", default = 40.0, min = 1.0, max = 120.0, description = "Body Freq")
bpy.types.Scene.Body_DegX_Freq = bpy.props.FloatProperty(name="Body_DegX_Freq", default = 24.0, min = 1.0, max = 90.0, description = "Body DegX Freq")
bpy.types.Scene.Body_DegY_Freq = bpy.props.FloatProperty(name="Body_DegY_Freq", default = 18.0, min = 1.0, max = 90.0, description = "Body DegY Freq")

bpy.types.Scene.Spine_face_Start = bpy.props.FloatProperty(name="Spine_face_Start", default = 0, min = 0.0, max = 180.0, description = "Spine face Start")
bpy.types.Scene.Spine_face_End = bpy.props.FloatProperty(name="Spine_face_End", default = 90, min = 0.0, max = 180.0, description = "Spine face End")
bpy.types.Scene.Spine_up_Start = bpy.props.FloatProperty(name="Spine_up_Start", default = 5, min = 1.0, max = 8.0, description = "Spine up Start")

bpy.types.Scene.Seed_up_Start = bpy.props.FloatProperty(name="Seed_up_Start", default = 1.0, min = 0.0, max = 8.0, description = "Seed up Start")
bpy.types.Scene.Seed_up_End = bpy.props.FloatProperty(name="Seed_up_End", default = 3.0, min = 0.0, max = 8.0, description = "Seed up End")

bpy.types.Scene.Root_up_Start = bpy.props.FloatProperty(name="Root_up_Start", default = 0.0, min = 0.0, max = 3.0, description = "Root up Start")
bpy.types.Scene.Root_up_End = bpy.props.FloatProperty(name="Root_up_End", default = 2.0, min = 0.0, max = 8.0, description = "Root_up_End")

bpy.types.Scene.Leaf_up_Start = bpy.props.FloatProperty(name="Leaf_up_Start", default = 7.0, min = 3.0, max = 10.0, description = "Leaf up Start")

bpy.types.Scene.Flower_Petal_Num = bpy.props.IntProperty(name="Flower_Petal_Num", default = 5, min = 3, max = 9, description = "Flower Petal Num")

# '''
register()