organizing into functions

This commit is contained in:
ForeignGods 2022-06-11 19:45:51 +02:00
parent 253a3a0da4
commit 83c2acd0cc
6 changed files with 650 additions and 541 deletions

View File

@ -2,131 +2,145 @@ import bpy
import random
from mathutils import Vector, Matrix
#variables
count = 50
cubes=[]
############################################################
# Bubble Sort Algorithm
############################################################
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(1,count+1))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
i = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[i]
cubes.append(ob)
i += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
#bubble sort
for i in range(count):
#insert keyframe for every cube on every frame
for cube in cubes:
cube.keyframe_insert(data_path="location", frame=i)
already_sorted = True
for j in range(count - i -1):
def bubble_sort(cubes, arrayCounter, comparisonCounter):
for i in range(len(cubes)-1):
#add 1 to comparison counter
comparisonCounter.inputs[0].default_value += 1
comparisonCounter.inputs[0].keyframe_insert(data_path='default_value', frame=i)
#insert keyframe for every cube on every frame
for cube in cubes:
cube.keyframe_insert(data_path="location", frame=i)
already_sorted = True
for j in range(len(cubes) - i -1):
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=i)
if cubes[j].scale.z > cubes[j + 1].scale.z:
#change location & insert keyframes based on bubble sort
cubes[j].location.x = j
cubes[j].keyframe_insert(data_path="location", frame=i)
cubes[j+1].location.x = j-1
cubes[j+1].keyframe_insert(data_path="location", frame=i)
#add 4 to array counter
arrayCounter.inputs[0].default_value += 4
#add 1 to comparison counter
comparisonCounter.inputs[0].default_value += 1
comparisonCounter.inputs[0].keyframe_insert(data_path='default_value', frame=i)
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=i)
#rearrange arrays
cubes[j], cubes[j + 1] = cubes[j + 1], cubes[j]
already_sorted = False
if already_sorted:
break
if cubes[j].scale.z > cubes[j + 1].scale.z:
#change location & insert keyframes based on bubble sort
cubes[j].location.x = j
cubes[j].keyframe_insert(data_path="location", frame=i)
cubes[j+1].location.x = j-1
cubes[j+1].keyframe_insert(data_path="location", frame=i)
#add 4 to array counter
arrayCounter.inputs[0].default_value += 4
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=i)
#rearrange arrays
cubes[j], cubes[j + 1] = cubes[j + 1], cubes[j]
already_sorted = False
if already_sorted:
break
############################################################
# Setup Random Cubes + Array to be sorted
############################################################
def setup_array(count):
#initialize array
cubes=[]
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the transform node of counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count-1))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count-1):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
s = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[s]+1
cubes.append(ob)
s += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
return (cubes, arrayCounter, comparisonCounter)
############################################################
# Call Functions
############################################################
cubes, arrayCounter, comparisonCounter = setup_array(20)
bubble_sort(cubes, arrayCounter, comparisonCounter)

View File

@ -6,7 +6,7 @@ from mathutils import Vector, Matrix
# Insertion Sort Algorithm
############################################################
def insertionSort(cubes, arrayCounter, comparisonCounter):
def insertion_sort(cubes, arrayCounter, comparisonCounter):
#start at frame 0
iframe=0
originFrame = 0
@ -18,8 +18,8 @@ def insertionSort(cubes, arrayCounter, comparisonCounter):
j = i - 1
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
#add 1 to array counter
arrayCounter.inputs[0].default_value += 1
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
while j >= 0 and cubes[j].scale.z > key_item.scale.z:
@ -36,8 +36,8 @@ def insertionSort(cubes, arrayCounter, comparisonCounter):
for cube in cubes:
cube.keyframe_insert(data_path="location", frame=iframe)
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
#add 3 to array counter
arrayCounter.inputs[0].default_value += 3
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
#add 1 to comparison counter
@ -73,10 +73,9 @@ def insertionSort(cubes, arrayCounter, comparisonCounter):
# Setup Random Cubes + Array to be sorted
############################################################
def setUpCubeArray():
def setup_array(count):
#variables
count = 50
#initialize array
cubes=[]
#delete every existing node_group
@ -170,12 +169,6 @@ def setUpCubeArray():
# Call Functions
############################################################
cubes, arrayCounter, comparisonCounter = setUpCubeArray()
cubes, arrayCounter, comparisonCounter = setup_array(12)
insertionSort(cubes, arrayCounter, comparisonCounter)
insertion_sort(cubes, arrayCounter, comparisonCounter)

View File

@ -1,137 +1,77 @@
from random import randint
import bpy
import random
from mathutils import Vector, Matrix
#variables
count = 150
cubes=[]
############################################################
# Merge Sort Algorithm
############################################################
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
def merge(arr, l, m, r, arrayCounter, comparisonCounter):
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
i = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[i]+1
cubes.append(ob)
i += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
def merge(arr, l, m, r):
global array
global cubes
global iframe
n1 = m - l + 1
n2 = r - m
# create temp arrays
#create temp arrays
L = [0] * (n1)
R = [0] * (n2)
# Copy data to temp arrays L[] and R[]
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
#copy data to temp arrays L[] and R[]
for i in range(0, n1):
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
L[i] = arr[l + i]
for j in range(0, n2):
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
R[j] = arr[m + 1 + j]
# Merge the temp arrays back into arr[l..r]
i = 0 # Initial index of first subarray
j = 0 # Initial index of second subarray
k = l # Initial index of merged subarray
#merge the temp arrays back into arr[l..r]
i = 0 #initial index of first subarray
j = 0 #initial index of second subarray
k = l #initial index of merged subarray
while i < n1 and j < n2:
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
#add 1 to comparison counter
comparisonCounter.inputs[0].default_value += 1
comparisonCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
if L[i].scale.z <= R[j].scale.z:
arr[k] = L[i]
L[i].location.x = k
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
i += 1
else:
arr[k] = R[j]
R[j].location.x = k
#add 3 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
j += 1
k += 1
for cube in array:
for cube in cubes:
cube.keyframe_insert(data_path="location", frame=iframe)
for cube in L:
cube.keyframe_insert(data_path="location", frame=iframe)
@ -140,14 +80,18 @@ def merge(arr, l, m, r):
iframe += 1
# Copy the remaining elements of L[], if there
# are any
#copy the remaining elements of L[], if there are any
while i < n1:
arr[k] = L[i]
L[i].location.x = k
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
x=0
for cube in array:
for cube in cubes:
cube.keyframe_insert(data_path="location", frame=iframe)
for cube in L:
cube.keyframe_insert(data_path="location", frame=iframe)
@ -158,13 +102,17 @@ def merge(arr, l, m, r):
i += 1
k += 1
# Copy the remaining elements of R[], if there
# are any
#copy the remaining elements of R[], if there are any
while j < n2:
arr[k] = R[j]
R[j].location.x = k
for cube in array:
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
for cube in cubes:
cube.keyframe_insert(data_path="location", frame=iframe)
for cube in L:
cube.keyframe_insert(data_path="location", frame=iframe)
@ -174,20 +122,120 @@ def merge(arr, l, m, r):
j += 1
k += 1
# l is for left index and r is right index of the
# sub-array of arr to be sorted
def mergeSort(arr, l, r):
#l is for left index and r is right index of the sub-array of arr to be sorted
def merge_sort(arr, l, r, arrayCounter, comparisonCounter):
if l < r:
# Same as (l+r)//2, but avoids overflow for
# large l and h
#same as (l+r)//2, but avoids overflow for large l and h
m = l+(r-l)//2
# Sort first and second halves
mergeSort(arr, l, m)
mergeSort(arr, m+1, r)
merge(arr, l, m, r)
#sort first and second halves
merge_sort(arr, l, m, arrayCounter, comparisonCounter)
merge_sort(arr, m+1, r, arrayCounter, comparisonCounter)
merge(arr, l, m, r, arrayCounter, comparisonCounter)
############################################################
# Setup Random Cubes + Array to be sorted
############################################################
def setup_array(count):
#initialize array
cubes=[]
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the transform node of counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count-1))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count-1):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
s = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[s]+1
cubes.append(ob)
s += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
return (cubes, arrayCounter, comparisonCounter)
############################################################
# Call Functions
############################################################
cubes, arrayCounter, comparisonCounter = setup_array(20)
iframe = 0
array = cubes
mergeSort(cubes, 0, count-1)
merge_sort(cubes, 0, len(cubes)-1, arrayCounter, comparisonCounter)

View File

@ -1,101 +1,13 @@
from random import randint
import bpy
import random
from mathutils import Vector, Matrix
#variables
count = 50
cubes=[]
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
i = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[i]+1
cubes.append(ob)
i += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
iframe=0
############################################################
# Quick Sort Algorithm
############################################################
# function to find the partition position
def partition(array, low, high):
def partition(array, low, high, arrayCounter, comparisonCounter):
global iframe
@ -147,18 +59,120 @@ def partition(array, low, high):
array[i], array[j] = array[j], array[i]
# function to perform quicksort
def quickSort(array, low, high):
def quick_sort(array, low, high, arrayCounter, comparisonCounter):
if low < high:
# find pivot element such that
# element smaller than pivot are on the left
# element greater than pivot are on the right
pi = partition(array, low, high)
pi = partition(array, low, high, arrayCounter, comparisonCounter)
# recursive call on the left of pivot
quickSort(array, low, pi)
quick_sort(array, low, pi, arrayCounter, comparisonCounter)
# recursive call on the right of pivot
quickSort(array, pi + 1, high)
quick_sort(array, pi + 1, high, arrayCounter, comparisonCounter)
quickSort(cubes, 0, len(cubes) - 1)
############################################################
# Setup Random Cubes + Array to be sorted
############################################################
def setup_array(count):
#initialize array
cubes=[]
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the transform node of counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count-1))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count-1):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
s = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[s]+1
cubes.append(ob)
s += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
return (cubes, arrayCounter, comparisonCounter)
############################################################
# Call Functions
############################################################
cubes, arrayCounter, comparisonCounter = setup_array(20)
iframe = 0
quick_sort(cubes, 0, len(cubes) - 1, arrayCounter, comparisonCounter)

View File

@ -1,100 +1,12 @@
from random import randint
import bpy
import random
from mathutils import Vector, Matrix
#variables
count = 50
cubes=[]
############################################################
# Selection Sort Algorithm
############################################################
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
i = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[i]+1
cubes.append(ob)
i += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
iframe = 0
#Selection Sort ALgorithm
def selection_sort(cubes):
def selection_sort(cubes, arrayCounter, comparisonCounter):
global iframe
@ -105,6 +17,15 @@ def selection_sort(cubes):
cube.keyframe_insert(data_path="location", frame= iframe)
for j in range(i , len(cubes)):
#add 2 to array counter
arrayCounter.inputs[0].default_value += 2
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
#add 1 to comparison counter
comparisonCounter.inputs[0].default_value += 1
comparisonCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
if cubes[min_idx].scale.z > cubes[j].scale.z:
min_idx = j
@ -115,7 +36,112 @@ def selection_sort(cubes):
cubes[min_idx].keyframe_insert(data_path="location", frame= iframe)
iframe +=1
#add 4 to array counter
arrayCounter.inputs[0].default_value += 4
arrayCounter.inputs[0].keyframe_insert(data_path='default_value', frame=iframe)
cubes[i], cubes[min_idx] = cubes[min_idx], cubes[i]
#Call Function
selection_sort(cubes)
############################################################
# Setup Random Cubes + Array to be sorted
############################################################
def setup_array(count):
#initialize array
cubes=[]
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the transform node of counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count-1))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count-1):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
s = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[s]+1
cubes.append(ob)
s += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
return (cubes, arrayCounter, comparisonCounter)
############################################################
# Call Functions
############################################################
cubes, arrayCounter, comparisonCounter = setup_array(20)
iframe = 0
selection_sort(cubes, arrayCounter, comparisonCounter)

View File

@ -1,101 +1,12 @@
from random import randint
import bpy
import random
from mathutils import Vector, Matrix
#variables
count = 50
cubes=[]
############################################################
# Shell Sort Algorithm
############################################################
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
i = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[i]+1
cubes.append(ob)
i += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
iframe=0
#Shell Sort Algorithm
def shellSort(arr, n):
def shellSort(arr, n, arrayCounter, comparisonCounter):
global iframe
@ -146,5 +57,108 @@ def shellSort(arr, n):
# If the element present is greater than current element
j+=1
gap=gap//2
############################################################
# Setup Random Cubes + Array to be sorted
############################################################
def setup_array(count):
#initialize array
cubes=[]
#delete every existing node_group
for grp in bpy.data.node_groups:
bpy.data.node_groups.remove(grp)
#delete every existing object
for ob in bpy.data.objects:
bpy.data.objects.remove(ob)
shellSort(cubes, count)
#add counter object, set position of counter object below other cube
bpy.ops.mesh.primitive_cube_add(location = (-2.5, 0, -3.375))
bpy.context.active_object.name = 'Counter'
#add geometry node modifier
bpy.ops.object.modifier_add(type='NODES')
#get and clear node_group
node_grp = bpy.data.node_groups[-1]
node_grp.nodes.clear()
#add nodes
stringToCurves = node_grp.nodes.new("GeometryNodeStringToCurves")
fillCurve = node_grp.nodes.new("GeometryNodeFillCurve")
transform = node_grp.nodes.new("GeometryNodeTransform")
joinStrings = node_grp.nodes.new("GeometryNodeStringJoin")
comparisonString = node_grp.nodes.new("FunctionNodeInputString")
comparisonCounter = node_grp.nodes.new("FunctionNodeValueToString")
arrayString = node_grp.nodes.new("FunctionNodeInputString")
arrayCounter = node_grp.nodes.new("FunctionNodeValueToString")
groupOutput = node_grp.nodes.new('NodeGroupOutput')
#90 degree rotation of the transform node of counter object
transform.inputs[2].default_value[0] = 1.5708
#set default values of some nodes
comparisonString.string = "Comparisons:"
arrayString.string = "Array Accesses:"
stringToCurves.inputs[1].default_value = 2
joinStrings.inputs[0].default_value = " "
#connect nodes to eachother
node_grp.links.new(fillCurve.outputs[0], groupOutput.inputs[0])
node_grp.links.new(transform.outputs[0], fillCurve.inputs[0])
node_grp.links.new(stringToCurves.outputs[0], transform.inputs[0])
node_grp.links.new(joinStrings.outputs[0], stringToCurves.inputs[0])
node_grp.links.new(comparisonCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(comparisonString.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayCounter.outputs[0], joinStrings.inputs[1])
node_grp.links.new(arrayString.outputs[0], joinStrings.inputs[1])
#fill arrays with numbers between 1 & count
ran = list(range(0,count-1))
#randomize array order
random.shuffle(ran)
#sets origin of cube to bottom of mesh
def origin_to_bottom(ob, matrix=Matrix()):
me = ob.data
mw = ob.matrix_world
local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
o = sum(local_verts, Vector()) / 8
o.z = min(v.z for v in local_verts)
o = matrix.inverted() @ o
me.transform(Matrix.Translation(-o))
mw.translation = mw @ o
#create cubes with random location
for i in range(count-1):
bpy.ops.mesh.primitive_cube_add(location=(ran[i], 0, 0), scale=(0.25, 0.25, 0.25))
#shuffle array
random.shuffle(ran)
#assign random scale to all cubes and add them to array
s = 0
for ob in bpy.data.objects:
if ob.type == 'MESH' and ob.name != "Counter":
origin_to_bottom(ob)
ob.scale.z = ran[s]+1
cubes.append(ob)
s += 1
#sort array based on location.x
cubes.sort(key = lambda obj: obj.location.x)
return (cubes, arrayCounter, comparisonCounter)
############################################################
# Call Functions
############################################################
cubes, arrayCounter, comparisonCounter = setup_array(20)
iframe = 0
shellSort(cubes, len(cubes), arrayCounter, comparisonCounter)