Last active
August 14, 2022 16:43
-
-
Save armindocachada/414f99127f0544f758970c103553e879 to your computer and use it in GitHub Desktop.
fully_connected_neural_network._blender.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import bmesh | |
import math | |
import numpy as np | |
def getGeometryCenter(obj): | |
vcos = [ obj.matrix_world @ v.co for v in obj.data.vertices ] | |
findCenter = lambda l: ( max(l) + min(l) ) / 2 | |
x,y,z = [ [ v[i] for v in vcos ] for i in range(3) ] | |
center = [ findCenter(axis) for axis in [x,y,z] ] | |
print(center) | |
return center | |
def setOrigin(obj): | |
oldLoc = obj.location | |
newLoc = getGeometryCenter(obj) | |
for vert in obj.data.vertices: | |
vert.co[0] -= newLoc[0] - oldLoc[0] | |
vert.co[1] -= newLoc[1] - oldLoc[1] | |
vert.co[2] -= newLoc[2] - oldLoc[2] | |
obj.location = newLoc | |
def calculateNeuronGrid(numberOfNodes, origin, neuron_size): | |
(rows, cols) = numberOfNodes | |
height = rows * neuron_size | |
width = cols * neuron_size | |
(origin_x, origin_y, origin_z) = origin | |
top_z = origin_z - (height / 2) | |
left_x = origin_x - (width / 2) | |
start_x = left_x + (neuron_size / 2) | |
start_y = origin_y | |
start_z = top_z + (neuron_size / 2) | |
row_height = height / rows | |
col_width = width / cols | |
neuron_coordinate_y = 0 | |
neurons_grid = np.zeros((rows, cols, 3)) | |
for row_index in range(0, rows): | |
neuron_coordinate_z = start_z + (row_index * row_height) | |
for col_index in range(0, cols): | |
neuron_coordinate_x = start_x + col_index * col_width | |
neurons_grid[row_index, col_index] = (neuron_coordinate_x, | |
start_y, | |
neuron_coordinate_z) | |
return neurons_grid.reshape( (rows * cols, 3)) | |
def neuronsLayer(numberOfNodes=(10,10), origin=(0,0,0), neuron_size = 1): | |
# Create an empty mesh and the object. | |
mesh = bpy.data.meshes.new('Basic_Sphere') | |
neuron_layer = bpy.data.objects.new("Neuron Layer", mesh) | |
neuron_layer.location= origin | |
# Add the object into the scene. | |
bpy.context.collection.objects.link(neuron_layer) | |
# Select the newly created object | |
bpy.context.view_layer.objects.active = neuron_layer | |
neuron_layer.select_set(True) | |
(nrows, ncols) = numberOfNodes | |
# Construct the bmesh sphere and assign it to the blender mesh. | |
bm = bmesh.new() | |
bmesh.ops.create_uvsphere(bm, u_segments=32, v_segments=16, radius=neuron_size/2) | |
bm.to_mesh(mesh) | |
bm.free() | |
mod = neuron_layer.modifiers.new('Array', 'ARRAY') | |
mod.relative_offset_displace[0] = 1 | |
mod.relative_offset_displace[1] = 0 | |
mod.count = nrows | |
bpy.ops.object.modifier_apply(modifier='Array') | |
mod = neuron_layer.modifiers.new('Array', 'ARRAY') | |
#print(type(mod)) | |
#print(mod.items()) | |
mod.relative_offset_displace[0] = 0 | |
mod.relative_offset_displace[1] = 0 | |
mod.relative_offset_displace[2] = 1 | |
mod.count = ncols | |
bpy.ops.object.modifier_apply(modifier='Array') | |
print(f"sphere.dimensions={neuron_layer.dimensions}") | |
setOrigin(neuron_layer) | |
neuron_layer.location=origin | |
neuron_grid = calculateNeuronGrid(numberOfNodes, origin, neuron_size) | |
return (neuron_layer, neuron_grid) | |
def connectLayers(layer1, layer2): | |
for neuron_layer1 in layer1: | |
for neuron_layer2 in layer2: | |
connectNeurons(neuron_layer1 ,neuron_layer2) | |
def midpoint(location_1, location_2): | |
(x1, y1, z1) = location_1 | |
(x2, y2, z2) = location_2 | |
x12 = (x1 +x2) / 2 | |
y12 = (y1+ y2) /2 | |
z12 = (z1 + z2)/ 2 | |
return (x12, y12, z12) | |
def distance(location_1, location_2): | |
(x1, y1, z1) = location_1 | |
(x2, y2, z2) = location_2 | |
distance = math.sqrt( (x2- x1)**2 + (y2- y1)**2 + (z2- z1)**2) | |
return distance | |
def determine_angle(vectora, vectorb): | |
(xa, ya, za) = vectora | |
(xb, yb, zb) = vectorb | |
dot_product= (xa * xb + ya * yb + za * zb) | |
sqrt_vectora = math.sqrt((xa ** 2 + ya**2 + za**2)) | |
sqrt_vectorb = math.sqrt((xb ** 2 + yb**2 + zb**2)) | |
product_sqrt = sqrt_vectora * sqrt_vectorb | |
angle = math.acos(dot_product / product_sqrt) | |
return angle | |
def connectNeurons( location_start, location_end): | |
x = location_end[0] - location_start[0] | |
y = location_end[1] - location_start[1] | |
z = location_end[2] - location_start[2] | |
dist = distance(location_end, location_start) | |
mag = math.sqrt(x**2 + y**2 ) | |
if x == 0: | |
beta = 0 | |
else: | |
beta = math.atan(y/x) | |
if (x <= 0 and y >= 0) or (x <= 0 and y <= 0): | |
beta = math.pi + beta | |
if mag == 0: | |
theta = pi/2 | |
else: | |
theta = math.atan(z/mag) | |
bpy.ops.mesh.primitive_cylinder_add( radius=0.1, depth=dist, scale=(1,1,1)) | |
gap = mag | |
cylinder = bpy.context.object | |
#cylinder.scale.z = gap/2 | |
cylinder.location = location_start + (location_end - location_start)/2 | |
#cylinder.location= location_start | |
cylinder.rotation_euler.z = beta | |
cylinder.rotation_euler.y = -theta + math.pi/2 | |
#def connectNeurons( location_start, location_end): | |
# dist = distance(location_start, location_end) | |
# midpt = midpoint(location_start, location_end) | |
# | |
# | |
# (mx, my, mz) = midpt | |
# | |
# | |
# rotate_z_vector = (mx, my, mz+1) | |
# print(rotate_z_vector) | |
# rotate_y_vector = (mx, my +1, mz) | |
# rotate_x_vector = (mx + 1, my, mz) | |
# | |
# angle_x = determine_angle( rotate_x_vector, rotate_z_vector) | |
# angle_y = determine_angle( rotate_y_vector,rotate_z_vector) | |
# | |
# | |
# print(f"midpoint{midpt}") | |
# angle = determine_angle((0.5,0, 1), location_end) | |
# print(f"angle={angle}") | |
# bpy.ops.mesh.primitive_cylinder_add( radius=0.1, depth=dist, location=midpt, scale=(1,1,1)) | |
# | |
# bpy.ops.transform.rotate(value=angle_x, orient_axis='X') | |
# bpy.ops.transform.rotate(value=angle_y, orient_axis='Y') | |
# #bpy.ops.transform.rotate(value=angle, orient_axis='Z') | |
(neuron_layer1, neuron_grid1) = neuronsLayer(numberOfNodes=(4,4), origin=(0,0,0)) | |
(neuron_layer2, neuron_grid2) = neuronsLayer(numberOfNodes=(2,2), origin=(0,10,0)) | |
connectLayers(neuron_grid1, neuron_grid2) | |
print(f"neuron_grid1: {neuron_grid1}") | |
print(f"neuron_grid2: {neuron_grid2}") | |
print(midpoint((0,0,0), (1, 1, 1))) | |
print(distance((0,0,0), (1, 1, 1))) | |
#connectNeurons(np.array((0,0,0)), np.array((1, 1, 1))) | |
#connectNeurons(np.array((2, 2, 2)), np.array((3,1,3))) | |
#[-0.5 0. -1.5] | |
#[ 0.5 10. -0.5] | |
#print(math.degrees(determine_angle( (1, 1, 2), (-4, -8, 6)))) | |
#math.radians(x) | |
#Convert angle x from degrees to radians. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment