Skip to content

Instantly share code, notes, and snippets.

@sjkillen
sjkillen / pattern.rs
Created December 21, 2023 19:10
Odd but useful Rust pattern to implement abstract methods and extend structs with additional fields
struct Base<Extension = ()> {
ext: Extension,
x: i32,
y: i32,
z: i32,
}
trait BaseAbstractMethods {
fn combine_components(&self, a: i32, b: i32) -> i32;
}
@sjkillen
sjkillen / bpy_toggle_armature_ik.py
Created September 17, 2023 20:01
Toggle the IK on a armature in Blender Python
import bpy
from bpy.props import IntProperty, FloatProperty
from bpy.types import Armature, PoseBone, KinematicConstraint, Object
def ik_constraints(armature: Object):
assert type(armature.data) is Armature
return (constraint for pbone in armature.pose.bones
for constraint in pbone.constraints
if type(constraint is KinematicConstraint))
@sjkillen
sjkillen / sort_mesh_uv.py
Last active August 30, 2023 21:00
Blender Python sort UV maps
from bpy.types import Mesh
def sort_uv_layers(mesh: Mesh):
# UV layers use non-pythonic reference semantics, safest to always reference by their indices
assert len(mesh.uv_layers) <= 7, "There must be fewer than 8 UV maps to sort (one less than the Blender maximum of 8)"
initial_layers = [[i, layer.name] for i, layer in enumerate(mesh.uv_layers)]
initial_layers.sort(key=itemgetter(1))
for i, layer_name in tuple(initial_layers):
assert mesh.uv_layers[i].name == layer_name, mesh.uv_layers[i].name + " " + layer_name
mesh.uv_layers.active = mesh.uv_layers[i]
def factorial(n, accumulator=1):
if n == 1:
return accumulator
return factorial(n - 1, accumulator * n)
try:
factorial(1000)
except RecursionError:
print("TOO MUCH RECURSION!")
from functools import singledispatch, wraps
from collections.abc import Iterable
def one_or_many(fn):
@wraps(fn)
@singledispatch
def wrapper(*args, **kwargs):
fn(*args, **kwargs)
@wrapper.register
@sjkillen
sjkillen / ReverseSkin.py
Created November 14, 2022 01:47
Create a simple mesh from an armature that can could create a similar armature using the skin modifier
import bpy
from bpy.types import Scene, Armature, Mesh
from operator import itemgetter
from itertools import chain
def create_geometry(armature: Armature) -> Mesh:
roots = tuple(bone for bone in armature.bones if bone.parent is None)
mesh = bpy.data.meshes.new(armature.name)
@sjkillen
sjkillen / quine.bash
Last active February 2, 2022 19:58
Infinitely looping program that demonstrates that bash programs are modifiable during execution
S='sleep 1; echo hello world; echo "$S" >> quine.bash; sleep 1'
sleep 1
echo hello world
echo "$S" >> quine.bash
sleep 1
@sjkillen
sjkillen / inum.rs
Created March 22, 2021 22:08
Unnecessary iterator abstraction
use std::iter::once;
#[derive(Debug)]
pub enum IterNum<T, I: Iterator<Item = T>> {
Zero,
One(T),
More(I),
}
pub fn inum<T, I: Iterator<Item = T>>(mut items: I) -> IterNum<T, impl Iterator<Item = T>> {
@sjkillen
sjkillen / main.rs
Last active March 17, 2022 08:31
Rust Cartesian Product Iterator
mod util;
use std::ops::Range;
use util::*;
fn main() {
let v: Vec<Range<i32>> = [(1..4), (11..14), (111..114)]
.into_iter()
.map(|r| r.clone())
.collect();
for items in v.into_iter().flat_cprod() {
@sjkillen
sjkillen / decide_nat_eq.lean
Last active June 7, 2020 15:28
ℕ = ℕ is decidable
open nat
/--
Decide whether two natural numbers are equal
(already included in LEAN standard lib)
-/
lemma eq_iff_succ_eq {a b : ℕ} : a = b <-> a+1 = b+1 :=
begin
split,