{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "b9f3df9e-c2ea-48a4-8ed2-a6402736fb86", "metadata": {}, "outputs": [], "source": [ "# File: hang.ipynb\n", "# Code: Claude Code and Codex\n", "# Review: Ryoichi Ando (ryoichi.ando@zozo.com)\n", "# License: Apache v2.0" ] }, { "cell_type": "code", "execution_count": null, "id": "950b418e-2ff8-429c-97b1-79f87304af40", "metadata": {}, "outputs": [], "source": [ "from frontend import App\n", "\n", "# create an app\n", "app = App.create(\"hang\")\n", "\n", "# make a sheet and add to the asset\n", "V, F = app.mesh.square(res=128, ex=[1, 0, 0], ey=[0, 1, 0])\n", "app.asset.add.tri(\"sheet\", V, F)\n", "\n", "# make a hanging sheet scene\n", "scene = app.scene.create()\n", "\n", "# hang a sheet and pin top two corners\n", "sheet = scene.add(\"sheet\")\n", "sheet.pin(sheet.grab([-1, 1, 0]) + sheet.grab([1, 1, 0]))\n", "\n", "# set strain-limiting upper bound\n", "sheet.param.set(\"strain-limit\", 0.01).set(\"young-mod\", 100).set(\"bend\", 1.0)\n", "\n", "# build the scene and preview\n", "scene = scene.build().report()\n", "scene.preview()" ] }, { "cell_type": "code", "execution_count": null, "id": "46a61c8b-126b-4e0f-8c11-cfc1cb465fab", "metadata": {}, "outputs": [], "source": [ "import random # noqa\n", "\n", "# set small jitter\n", "jitter_time = 0.1 + 0.5 * random.random()\n", "\n", "# build a new session\n", "session = app.session.create(scene)\n", "\n", "# obtain default gravity value\n", "gravity = session.param.get(\"gravity\")\n", "\n", "# set the maximal video frame to 200\n", "session.param.set(\"frames\", 200)\n", "\n", "# set dynamic gravity\n", "(\n", " session.param.dyn(\"gravity\") # focus on gravity\n", " .time(1) # move the time cursor to 1 second\n", " .hold() # hold the current value\n", " .time(1 + jitter_time) # move the time cursor slightly forward\n", " .change([-g for g in gravity]) # flip the gravity\n", " .time(2.0) # move the time cursor to 2 seconds\n", " .change(gravity) # flip back the gravity\n", ")\n", "\n", "session = session.build()" ] }, { "cell_type": "code", "execution_count": null, "id": "d9c3f1b7-bc8d-4c49-8d83-9b0ce95b9c95", "metadata": {}, "outputs": [], "source": [ "session.start().preview()\n", "session.stream()" ] }, { "cell_type": "code", "execution_count": null, "id": "45fa755d-8e22-41e3-8a91-0e9dcbd8ee14", "metadata": {}, "outputs": [], "source": [ "# run this cell after sufficnt frames are simulated\n", "session.animate()" ] }, { "cell_type": "code", "execution_count": null, "id": "a01ce8aa-e0bb-4f38-bb43-d148b3222194", "metadata": {}, "outputs": [], "source": [ "# export all simulated frames and make a zip file\n", "session.export.animation().zip()" ] }, { "cell_type": "code", "execution_count": null, "id": "546a1545-2238-4512-b88c-27d4d0a0b2ec", "metadata": {}, "outputs": [], "source": [ "# this is for CI\n", "if app.ci:\n", " assert session.finished()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }