Example
This example demonstrates the basic usage of Tölvera.
It will display a window with a black background.
from tolvera import Tolvera, run
def main(**kwargs):
tv = Tolvera(**kwargs)
@tv.render
def _():
return tv.px
if __name__ == '__main__':
run(main)
Example
Here's an annotated version of the above example:
# First, we import Tolvera and run() from tolvera.
from tolvera import Tolvera, run
# Then, we define a main function which takes in keyword arguments
# (kwargs) from the command line.
def main(**kwargs):
# Inside the main function, we initialise a Tolvera instance
# with the given keyword arguments.
tv = Tolvera(**kwargs)
# We use the render() decorator to render the pixels.
# This function can be named anything.
# It will run in a loop until the user exits the program.
@tv.render
def _():
# render() must return Pixels. Often, these pixels will be
# the pixels of the Tolvera instance, accessed with tv.px.
return tv.px
# Finally, we call run() with the main function as the argument.
if __name__ == '__main__':
run(main)
When Tolvera is run, messages will be printed to the console.
These messages inform the user of the status of Tolvera,
during initialisation, setup, and running.
Tolvera
Tolvera main class.
Attributes:
Name |
Type |
Description |
`name` |
str
|
Name of Tölvera instance.
|
`ctx` |
TolveraContext
|
|
`speed` |
float
|
|
`pn` |
int
|
|
`sn` |
int
|
|
`p_per_s` |
int
|
Number of particles per species.
|
`substep` |
int
|
Number of substeps per frame.
|
`iml` |
int
|
Dict of IML instances via anguilla.
|
`cv` |
int
|
computer vision integration via OpenCV.
|
`osc` |
int
|
|
`ti` |
int
|
Taichi (graphics backend).
|
Source code in src/tolvera/tolvera_.py
| class Tolvera:
"""Tolvera main class.
Attributes:
`name` (str): Name of Tölvera instance.
`ctx` (TolveraContext): Shared TolveraContext.
`speed` (float): Global timebase speed.
`pn` (int): Number of particles.
`sn` (int): Number of species.
`p_per_s` (int): Number of particles per species.
`substep` (int): Number of substeps per frame.
`iml`: Dict of IML instances via anguilla.
`cv`: computer vision integration via OpenCV.
`osc`: OSC via iipyper.
`ti`: Taichi (graphics backend).
"""
def __init__(self, **kwargs):
"""
Initialise and setup Tölvera with given keyword arguments.
Args:
name (str): Name of Tölvera instance. Defaults to "Tölvera".
ctx (TolveraContext): TolveraContext to share. Defaults to None.
see also kwargs for Tolvera.setup().
"""
self.kwargs = kwargs
self.name = kwargs.get("name", "Tölvera")
self.name_clean = clean_name(self.name)
if "ctx" not in kwargs:
self.init_context(**kwargs)
else:
self.share_context(kwargs["ctx"])
self.setup(**kwargs)
print(f"[{self.name}] Initialisation and setup complete.")
def init_context(self, **kwargs):
"""Initiliase TölveraContext with given keyword arguments.
Args:
**kwargs: Keyword arguments for TölveraContext.
"""
context = TolveraContext(**kwargs)
self.share_context(context)
def share_context(self, context):
"""Share TölveraContext with another Tölvera instance.
Args:
context: TölveraContext to share.
"""
if len(context.get_names()) == 0:
print(f"[{self.name}] Sharing context '{context.name}'.")
else:
print(
f"[{self.name}] Sharing context '{context.name}' with {context.get_names()}."
)
self.ctx = context
self.x = context.x
self.y = context.y
self.ti = context.ti
self.show = context.show
self.canvas = context.canvas
self.osc = context.osc
self.s = context.s
self.iml = context.iml
self.render = context.render
self.cleanup = context.cleanup
self.cv = context.cv
self.hands = context.hands
self.pose = context.pose
self.face = context.face
self.face_mesh = context.face_mesh
def setup(self, **kwargs):
"""
Setup Tölvera with given keyword arguments.
This can be called multiple throughout the lifetime of a Tölvera instance.
Args:
**kwargs: Keyword arguments for setup.
speed (float): Global timebase speed. Defaults to 1.
particles (int): Number of particles. Defaults to 1024.
species (int): Number of species. Defaults to 4.
substep (int): Number of substeps per frame. Defaults to 1.
See also kwargs for Pixels, Species, Particles, and Vera.
"""
self._speed = kwargs.get("speed", 1) # global timebase
self.particles = kwargs.get("particles", 1024)
self.species = kwargs.get("species", 4)
if self.particles < self.species:
self.species = self.particles
self.pn = self.particles
self.sn = self.species
self.p_per_s = self.particles // self.species
self.substep = kwargs.get("substep", 1)
self.px = Pixels(self, **kwargs)
self._species = Species(self, **kwargs)
self.p = Particles(self, **kwargs)
self.speed(self._speed)
self.v = Vera(self, **kwargs)
if self.osc is not False:
self.add_to_osc_map()
if self.cv is not False:
if self.hands:
self.hands.px = self.px
if self.pose:
self.pose.px = self.px
if self.face:
self.face.px = self.px
if self.face_mesh:
self.face_mesh.px = self.px
self.ctx.add(self)
print(f"[{self.name}] Setup complete.")
def randomise(self):
"""
Randomise particles, species, and Vera.
"""
self.p.randomise()
self.s.species.randomise()
self.v.randomise()
def reset(self, **kwargs):
"""
Reset Tölvera with given keyword arguments.
This will call setup() with given keyword arguments, but not init().
Args:
**kwargs: Keyword arguments for reset.
"""
print(f"[{self.name}] Resetting self with kwargs={kwargs}...")
if kwargs is not None:
self.kwargs = kwargs
self.setup()
def speed(self, speed: float = None):
"""Set or get global timebase speed."""
if speed is not None:
self._speed = speed
self.p.speed(speed)
return self._speed
def add_to_osc_map(self):
"""
Add top-level Tölvera functions to OSCMap.
"""
setter_name = f"{self.name_clean}_set"
getter_name = f"{self.name_clean}_get"
self.osc.map.receive_args_inline(setter_name + "_randomise", self.randomise)
# self.osc.map.receive_args_inline(setter_name+'_reset', self.reset) # TODO: kwargs?
self.osc.map.receive_args_inline(
setter_name + "_particles_randomise", self.p._randomise
) # TODO: move inside Particles
@self.osc.map.receive_args(speed=(1, 0, 100), count=1)
def tolvera_set_speed(speed: float):
"""Set global timebase speed."""
self.speed(speed)
|
__init__(**kwargs)
Initialise and setup Tölvera with given keyword arguments.
Parameters:
Name |
Type |
Description |
Default |
name |
str
|
Name of Tölvera instance. Defaults to "Tölvera".
|
required
|
ctx |
TolveraContext
|
TolveraContext to share. Defaults to None.
|
required
|
Source code in src/tolvera/tolvera_.py
| def __init__(self, **kwargs):
"""
Initialise and setup Tölvera with given keyword arguments.
Args:
name (str): Name of Tölvera instance. Defaults to "Tölvera".
ctx (TolveraContext): TolveraContext to share. Defaults to None.
see also kwargs for Tolvera.setup().
"""
self.kwargs = kwargs
self.name = kwargs.get("name", "Tölvera")
self.name_clean = clean_name(self.name)
if "ctx" not in kwargs:
self.init_context(**kwargs)
else:
self.share_context(kwargs["ctx"])
self.setup(**kwargs)
print(f"[{self.name}] Initialisation and setup complete.")
|
add_to_osc_map()
Add top-level Tölvera functions to OSCMap.
Source code in src/tolvera/tolvera_.py
| def add_to_osc_map(self):
"""
Add top-level Tölvera functions to OSCMap.
"""
setter_name = f"{self.name_clean}_set"
getter_name = f"{self.name_clean}_get"
self.osc.map.receive_args_inline(setter_name + "_randomise", self.randomise)
# self.osc.map.receive_args_inline(setter_name+'_reset', self.reset) # TODO: kwargs?
self.osc.map.receive_args_inline(
setter_name + "_particles_randomise", self.p._randomise
) # TODO: move inside Particles
@self.osc.map.receive_args(speed=(1, 0, 100), count=1)
def tolvera_set_speed(speed: float):
"""Set global timebase speed."""
self.speed(speed)
|
init_context(**kwargs)
Initiliase TölveraContext with given keyword arguments.
Parameters:
Name |
Type |
Description |
Default |
**kwargs |
|
Keyword arguments for TölveraContext.
|
{}
|
Source code in src/tolvera/tolvera_.py
| def init_context(self, **kwargs):
"""Initiliase TölveraContext with given keyword arguments.
Args:
**kwargs: Keyword arguments for TölveraContext.
"""
context = TolveraContext(**kwargs)
self.share_context(context)
|
randomise()
Randomise particles, species, and Vera.
Source code in src/tolvera/tolvera_.py
| def randomise(self):
"""
Randomise particles, species, and Vera.
"""
self.p.randomise()
self.s.species.randomise()
self.v.randomise()
|
reset(**kwargs)
Reset Tölvera with given keyword arguments.
This will call setup() with given keyword arguments, but not init().
Parameters:
Name |
Type |
Description |
Default |
**kwargs |
|
Keyword arguments for reset.
|
{}
|
Source code in src/tolvera/tolvera_.py
| def reset(self, **kwargs):
"""
Reset Tölvera with given keyword arguments.
This will call setup() with given keyword arguments, but not init().
Args:
**kwargs: Keyword arguments for reset.
"""
print(f"[{self.name}] Resetting self with kwargs={kwargs}...")
if kwargs is not None:
self.kwargs = kwargs
self.setup()
|
setup(**kwargs)
Setup Tölvera with given keyword arguments.
This can be called multiple throughout the lifetime of a Tölvera instance.
Parameters:
Name |
Type |
Description |
Default |
**kwargs |
|
Keyword arguments for setup.
speed (float): Global timebase speed. Defaults to 1.
particles (int): Number of particles. Defaults to 1024.
species (int): Number of species. Defaults to 4.
substep (int): Number of substeps per frame. Defaults to 1.
|
{}
|
Source code in src/tolvera/tolvera_.py
| def setup(self, **kwargs):
"""
Setup Tölvera with given keyword arguments.
This can be called multiple throughout the lifetime of a Tölvera instance.
Args:
**kwargs: Keyword arguments for setup.
speed (float): Global timebase speed. Defaults to 1.
particles (int): Number of particles. Defaults to 1024.
species (int): Number of species. Defaults to 4.
substep (int): Number of substeps per frame. Defaults to 1.
See also kwargs for Pixels, Species, Particles, and Vera.
"""
self._speed = kwargs.get("speed", 1) # global timebase
self.particles = kwargs.get("particles", 1024)
self.species = kwargs.get("species", 4)
if self.particles < self.species:
self.species = self.particles
self.pn = self.particles
self.sn = self.species
self.p_per_s = self.particles // self.species
self.substep = kwargs.get("substep", 1)
self.px = Pixels(self, **kwargs)
self._species = Species(self, **kwargs)
self.p = Particles(self, **kwargs)
self.speed(self._speed)
self.v = Vera(self, **kwargs)
if self.osc is not False:
self.add_to_osc_map()
if self.cv is not False:
if self.hands:
self.hands.px = self.px
if self.pose:
self.pose.px = self.px
if self.face:
self.face.px = self.px
if self.face_mesh:
self.face_mesh.px = self.px
self.ctx.add(self)
print(f"[{self.name}] Setup complete.")
|
share_context(context)
Share TölveraContext with another Tölvera instance.
Parameters:
Name |
Type |
Description |
Default |
context |
|
|
required
|
Source code in src/tolvera/tolvera_.py
| def share_context(self, context):
"""Share TölveraContext with another Tölvera instance.
Args:
context: TölveraContext to share.
"""
if len(context.get_names()) == 0:
print(f"[{self.name}] Sharing context '{context.name}'.")
else:
print(
f"[{self.name}] Sharing context '{context.name}' with {context.get_names()}."
)
self.ctx = context
self.x = context.x
self.y = context.y
self.ti = context.ti
self.show = context.show
self.canvas = context.canvas
self.osc = context.osc
self.s = context.s
self.iml = context.iml
self.render = context.render
self.cleanup = context.cleanup
self.cv = context.cv
self.hands = context.hands
self.pose = context.pose
self.face = context.face
self.face_mesh = context.face_mesh
|
speed(speed=None)
Set or get global timebase speed.
Source code in src/tolvera/tolvera_.py
| def speed(self, speed: float = None):
"""Set or get global timebase speed."""
if speed is not None:
self._speed = speed
self.p.speed(speed)
return self._speed
|