HeWo's Face
HeWo Face Engine is a real-time expressive face renderer built with Pygame — designed to bring characters like HeWo to life through geometry, emotion control, and animation.
Originally conceived as a minimalist face prototype, it has evolved into a full-featured engine capable of handling smooth emotional transitions, blinking, talking animations, and even multimedia overlays.
The package is modular by design, making it ideal for Standalone visual experiments or Integration into robotics pipelines (e.g., ROS 2 nodes)
It runs in real time and can be fully controlled via keyboard or HTTP API.
HeWo’s expressions are not pre-rendered: they’re algebraic. Every eye blink, mouth movement or smile is generated by morphing geometric primitives — fast, lightweight, and customizable.
Installation
To install the package:
pip install hewo-face
To launch the main application:
hewo_face_main
Controls
Keyboard
These controls are available when running the application interactively:
| Key | Action |
|---|---|
SPACE |
Toggle between increase/decrease mode |
1 |
Toggle talking animation |
2 |
Trigger blink |
M |
Set a random facial expression |
N |
Reset emotion to neutral |
V |
Increase face size |
B |
Decrease face size |
↑ ↓ ← → |
Move the face up/down/left/right |
Q–C |
Adjust individual emotion points (mapped) |
In adjust mode, each key from Q to C is mapped to one facial parameter.
Pressing them will increase or decrease the corresponding value depending on the current mode (SPACE toggles it).
API (REST)
If launched with the REST endpoint enabled, the following routes are available:
Routes Summary
| Endpoint | Method | Description |
|---|---|---|
/set_layout |
POST | Switches current layout |
/hewo/set_emotion_goal |
POST | Sets full emotion configuration |
/hewo/adjust_emotion/<param> |
POST | Sets value of a single face point |
/hewo/get_emotion |
GET | Retrieves current face values |
/hewo/adjust_position |
POST | Moves the face by (dx, dy) |
/hewo/set_size |
POST | Sets global face size |
/hewo/toggle_talk |
POST | Starts or stops talking animation |
/hewo/trigger_blink |
POST | Triggers a blink |
/hewo/set_random_emotion |
POST | Randomizes all emotion values |
/hewo/reset_emotion |
POST | Resets all emotion values to neutral |
/media/add |
POST | Adds a multimedia object |
/media/move |
POST | Moves multimedia object |
/media/set_position |
POST | Sets exact position of object |
/media/play |
POST | Starts playback |
/media/pause |
POST | Pauses playback |
/media/remove |
POST | Removes object from layout |
Layout API
curl -X POST "$BASE_URL/set_layout" \
-H "Content-Type: application/json" \
-d '{"name": "hewo"}'
🎭 Face API
curl -X POST "$BASE_URL/hewo/set_emotion_goal" \
-H "Content-Type: application/json" \
-d '{"lps":100,"letl_a":0,"letl_b":0,"letl_c":0,"lebl_a":0,"lebl_b":0,"lebl_c":0,"rps":100,"retl_a":0,"retl_b":0,"retl_c":0,"rebl_a":0,"rebl_b":0,"rebl_c":0,"tl_a":0,"tl_b":0,"tl_c":0,"tl_d":0,"tl_e":0,"bl_a":0,"bl_b":0,"bl_c":0,"bl_d":0,"bl_e":0}'
curl -X POST "$BASE_URL/hewo/adjust_emotion/lps" \
-H "Content-Type: application/json" \
-d '{"value": 73}'
curl -X GET "$BASE_URL/hewo/get_emotion"
curl -X POST "$BASE_URL/hewo/adjust_position" \
-H "Content-Type: application/json" \
-d '{"dx": 15, "dy": -10}'
curl -X POST "$BASE_URL/hewo/set_size" \
-H "Content-Type: application/json" \
-d '{"value": 300}'
curl -X POST "$BASE_URL/hewo/toggle_talk"
curl -X POST "$BASE_URL/hewo/trigger_blink"
curl -X POST "$BASE_URL/hewo/set_random_emotion"
curl -X POST "$BASE_URL/hewo/reset_emotion"
🖼️ Multimedia API
curl -X POST "$BASE_URL/media/add" \
-H "Content-Type: application/json" \
-d '{
"filepath": "/path/to/video.mov",
"position": [100, 200],
"velocity": [0, 0],
"size": [300, 200],
"loop": false,
"audio": true,
"autoplay": false,
"name": "VideoObj1"
}'
curl -X POST "$BASE_URL/media/move" \
-H "Content-Type: application/json" \
-d '{"name": "VideoObj1", "dx": 50, "dy": 20}'
curl -X POST "$BASE_URL/media/set_position" \
-H "Content-Type: application/json" \
-d '{"name": "VideoObj1", "x": 100, "y": 100}'
curl -X POST "$BASE_URL/media/play" \
-H "Content-Type: application/json" \
-d '{"name": "VideoObj1"}'
curl -X POST "$BASE_URL/media/pause" \
-H "Content-Type: application/json" \
-d '{"name": "VideoObj1"}'
curl -X POST "$BASE_URL/media/remove" \
-H "Content-Type: application/json" \
-d '{"name": "VideoObj1"}'
Notes
- All routes assume the app is running at
http://127.0.0.1:8000 - Replace
$BASE_URLwith your actual endpoint address if running remotely. - Current layouts:
"hewo"and"media"— more can be added as needed. - Face points (
lps,tl_a,bl_c, etc.) range from 0 to 100 and define facial expressions.
Metadata
Release files for hewo-face 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hewo_face-1.0.1.tar.gz | 20.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hewo_face-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.3 kB
Release files / hewo_face-1.0.1.tar.gz
| Download URL | hewo_face-1.0.1.tar.gz |
|---|---|
| Size | 20.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96f72f04f39786cedb875a6bd74caa7597840696dcfca0d2c7a9c04475d95bdc
|
|
BLAKE2b-256 checksum How to use checksums |
8384de287940fb972de5f55620941436c8b1f611c9cfdc8f9edf3eda5da9fb19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.18
|
Release files / hewo_face-1.0.1-py3-none-any.whl
| Download URL | hewo_face-1.0.1-py3-none-any.whl |
|---|---|
| Size | 23.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
66e3d78dfc3ddf1a4cac2b8ee460f9836356ab01eb13f4f8de39b9069a1739f6
|
|
BLAKE2b-256 checksum How to use checksums |
e71c145c2138421be15320475fa655f5d02b3994dd6811c4c27ef2441be91e91
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.18
|