Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Bio-IT
EPUG
Commits
0340b890
Verified
Commit
0340b890
authored
Nov 24, 2020
by
Renato Alves
🌱
Browse files
Add session 12 - 2020
parent
f84d9d6d
Changes
2
Hide whitespace changes
Inline
Side-by-side
meetings/2020/session_12_python_and_blender/README.md
0 → 100644
View file @
0340b890
# Python and Blender
In this session Kimberly Meechan introduced how she uses Blender (https://blender.org) in her scientific projects.
The files used in this session can be found at: https://git.embl.de/meechan/blender_intro
A slightly more advanced example is included in this repository (see
`cube_scrambler_panel.py`
)
meetings/2020/session_12_python_and_blender/cube_scrambler_panel.py
0 → 100644
View file @
0340b890
import
bpy
from
math
import
radians
,
degrees
,
isclose
import
mathutils
global
current_frame
current_frame
=
1.0
def
update_keyframes
():
global
current_frame
current_frame
+=
1.0
for
obj
in
bpy
.
data
.
objects
:
obj
.
keyframe_insert
(
data_path
=
"location"
,
frame
=
current_frame
)
obj
.
keyframe_insert
(
data_path
=
"rotation_quaternion"
,
frame
=
current_frame
)
def
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
axis
):
# Deal with cubie location
# Translate to centre, rotate, and translate back
rotation_centre
=
centre_cube
.
location
translate_to_centre
=
mathutils
.
Matrix
.
Translation
(
rotation_centre
-
cubie
.
location
)
rotation
=
mathutils
.
Matrix
.
Rotation
(
radians
(
angle
),
4
,
axis
)
translate_back
=
translate_to_centre
.
copy
()
translate_back
.
invert
()
full_matrix
=
translate_to_centre
@
rotation
@
translate_back
cubie
.
location
=
cubie
.
location
+
full_matrix
.
to_translation
()
# Deal with cubie rotation, using quaternions
if
axis
==
'X'
:
axis_vector
=
(
1.0
,
0.0
,
0.0
)
elif
axis
==
'Y'
:
axis_vector
=
(
0.0
,
1.0
,
0.0
)
elif
axis
==
'Z'
:
axis_vector
=
(
0.0
,
0.0
,
1.0
)
cubie
.
rotation_mode
=
'QUATERNION'
cubie
.
rotation_quaternion
=
mathutils
.
Quaternion
(
axis_vector
,
radians
(
angle
))
@
cubie
.
rotation_quaternion
def
rotate_cube
(
command
,
cubie
,
centre_cube
,
angle
):
if
command
==
"F"
:
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
'Y'
)
elif
command
==
"F'"
:
rotate_about_centre
(
cubie
,
centre_cube
,
-
angle
,
'Y'
)
if
command
==
"L"
:
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
'X'
)
elif
command
==
"L'"
:
rotate_about_centre
(
cubie
,
centre_cube
,
-
angle
,
'X'
)
if
command
==
"R"
:
rotate_about_centre
(
cubie
,
centre_cube
,
-
angle
,
'X'
)
elif
command
==
"R'"
:
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
'X'
)
if
command
==
"B"
:
rotate_about_centre
(
cubie
,
centre_cube
,
-
angle
,
'Y'
)
elif
command
==
"B'"
:
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
'Y'
)
if
command
==
"U"
:
rotate_about_centre
(
cubie
,
centre_cube
,
-
angle
,
'Z'
)
elif
command
==
"U'"
:
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
'Z'
)
if
command
==
"D"
:
rotate_about_centre
(
cubie
,
centre_cube
,
angle
,
'Z'
)
elif
command
==
"D'"
:
rotate_about_centre
(
cubie
,
centre_cube
,
-
angle
,
'Z'
)
def
rotate_face
(
command
,
centre_cube
,
paired_cubes
):
for
i
in
range
(
0
,
45
):
for
cubie
in
paired_cubes
:
rotate_cube
(
command
,
cubie
,
centre_cube
,
2
)
rotate_cube
(
command
,
centre_cube
,
centre_cube
,
2
)
update_keyframes
()
def
find_face
(
command
):
centre_cube
=
None
paired_cubes
=
[]
# Distance tolerance for matching cube locations
tol
=
1e-4
for
cube
in
bpy
.
data
.
collections
[
'Cubies'
].
all_objects
:
if
command
==
"F"
or
command
==
"F'"
:
if
isclose
(
cube
.
location
.
y
,
-
2
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
x
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
z
,
0
,
abs_tol
=
tol
):
centre_cube
=
cube
elif
isclose
(
cube
.
location
.
y
,
-
2
,
abs_tol
=
tol
):
paired_cubes
.
append
(
cube
)
if
command
==
"R"
or
command
==
"R'"
:
if
isclose
(
cube
.
location
.
y
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
x
,
2
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
z
,
0
,
abs_tol
=
tol
):
centre_cube
=
cube
elif
isclose
(
cube
.
location
.
x
,
2
,
abs_tol
=
tol
):
paired_cubes
.
append
(
cube
)
if
command
==
"L"
or
command
==
"L'"
:
if
isclose
(
cube
.
location
.
y
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
x
,
-
2
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
z
,
0
,
abs_tol
=
tol
):
centre_cube
=
cube
elif
isclose
(
cube
.
location
.
x
,
-
2
,
abs_tol
=
tol
):
paired_cubes
.
append
(
cube
)
if
command
==
"B"
or
command
==
"B'"
:
if
isclose
(
cube
.
location
.
y
,
2
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
x
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
z
,
0
,
abs_tol
=
tol
):
centre_cube
=
cube
elif
isclose
(
cube
.
location
.
y
,
2
,
abs_tol
=
tol
):
paired_cubes
.
append
(
cube
)
if
command
==
"U"
or
command
==
"U'"
:
if
isclose
(
cube
.
location
.
y
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
x
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
z
,
2
,
abs_tol
=
tol
):
centre_cube
=
cube
elif
isclose
(
cube
.
location
.
z
,
2
,
abs_tol
=
tol
):
paired_cubes
.
append
(
cube
)
if
command
==
"D"
or
command
==
"D'"
:
if
isclose
(
cube
.
location
.
y
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
x
,
0
,
abs_tol
=
tol
)
and
isclose
(
cube
.
location
.
z
,
-
2
,
abs_tol
=
tol
):
centre_cube
=
cube
elif
isclose
(
cube
.
location
.
z
,
-
2
,
abs_tol
=
tol
):
paired_cubes
.
append
(
cube
)
return
centre_cube
,
paired_cubes
def
rotate_whole_cube
(
command
):
centre_cube
,
paired_cubes
=
find_face
(
command
)
rotate_face
(
command
,
centre_cube
,
paired_cubes
)
def
scramble
():
scramble_string
=
bpy
.
context
.
scene
.
cube_settings
.
scramble
bpy
.
context
.
scene
.
frame_set
(
1.0
)
global
current_frame
current_frame
=
1.0
for
obj
in
bpy
.
data
.
objects
:
obj
.
animation_data_clear
()
obj
.
keyframe_insert
(
data_path
=
"location"
,
frame
=
current_frame
)
obj
.
keyframe_insert
(
data_path
=
"rotation_quaternion"
,
frame
=
current_frame
)
for
i
in
range
(
0
,
len
(
scramble_string
)):
command
=
scramble_string
[
i
]
if
i
+
1
<
len
(
scramble_string
):
next_letter
=
scramble_string
[
i
+
1
]
else
:
next_letter
=
""
if
command
==
"'"
:
continue
if
next_letter
==
"'"
:
command
+=
next_letter
rotate_whole_cube
(
command
)
bpy
.
context
.
scene
.
frame_set
(
current_frame
)
class
scrambler_settings
(
bpy
.
types
.
PropertyGroup
):
scramble
:
bpy
.
props
.
StringProperty
(
name
=
'scramble'
,
default
=
""
,
description
=
"sequence of moves to scramble cube"
)
class
SCRAMBLER_PT_panel
(
bpy
.
types
.
Panel
):
"""Cube scrambler panel"""
bl_label
=
"Cube Scrambler"
bl_space_type
=
'PROPERTIES'
bl_region_type
=
'WINDOW'
bl_context
=
"object"
def
draw
(
self
,
context
):
layout
=
self
.
layout
row
=
layout
.
row
()
row
.
label
(
text
=
'Cube moves:'
)
row
=
layout
.
row
()
row
.
prop
(
bpy
.
context
.
scene
.
cube_settings
,
'scramble'
,
text
=
'moves'
)
row
=
layout
.
row
()
row
.
operator
(
'object.scrambler_operator'
,
text
=
'Scramble!'
)
class
SCRAMBLER_OT_operator
(
bpy
.
types
.
Operator
):
"""Scrambles cube"""
bl_idname
=
"object.scrambler_operator"
bl_label
=
"scrambles_cube"
def
execute
(
self
,
context
):
scramble
()
return
{
'FINISHED'
}
def
register
():
bpy
.
utils
.
register_class
(
SCRAMBLER_PT_panel
)
bpy
.
utils
.
register_class
(
SCRAMBLER_OT_operator
)
bpy
.
utils
.
register_class
(
scrambler_settings
)
bpy
.
types
.
Scene
.
cube_settings
=
bpy
.
props
.
PointerProperty
(
type
=
scrambler_settings
)
def
unregister
():
bpy
.
utils
.
unregister_class
(
SCRAMBLER_PT_panel
)
bpy
.
utils
.
unregister_class
(
SCRAMBLER_OT_operator
)
bpy
.
utils
.
unregister_class
(
scrambler_settings
)
if
__name__
==
"__main__"
:
register
()
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment