{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "018dce87-1bf3-4ba5-9876-088319ecf75d", "metadata": {}, "outputs": [], "source": [ "# File: large-five-twist.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": "2eb84f3d-b318-4313-9004-d661aa55d39a", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from frontend import App\n", "\n", "# make an app\n", "app = App.create(\"large-five-twist\")\n", "\n", "# create a large cylinder mesh with specified radius and length\n", "half_length = 2.0 / 0.75\n", "V, F = app.mesh.cylinder(r=1, min_x=-half_length, max_x=half_length, n=1181)\n", "\n", "# add to the asset and name it \"cylinder\"\n", "app.asset.add.tri(\"cylinder\", V, F)\n", "\n", "# create a scene\n", "scene = app.scene.create()\n", "objs = []\n", "\n", "# arrange 5 cylinders in a circular pattern with larger radius\n", "n, r = 5, 1.75\n", "for i in range(5):\n", " t = 2 * i / n * np.pi\n", " x, y = r * np.cos(t), r * np.sin(t)\n", " objs.append(scene.add(\"cylinder\").at(0, x, y))\n", "\n", "# configure material properties and animations for each cylinder\n", "for obj in objs:\n", "\n", " # set bending stiffness, contact gap, Young's modulus, Poisson's ratio and density\n", " (\n", " obj.param.set(\"bend\", 500.0)\n", " .set(\"contact-gap\", 1.75e-3)\n", " .set(\"young-mod\", 1e4)\n", " .set(\"poiss-rat\", 0.25)\n", " .set(\"density\", 3.5)\n", " )\n", "\n", " # define animation parameters for large twisting motion\n", " angular_vel, move_delta, scale, t_end, t_wait, s_wait = (\n", " 180,\n", " 1,\n", " 0.25,\n", " 34,\n", " 500 / 60,\n", " 16,\n", " )\n", " x, y, z = obj.position\n", "\n", " # pin and animate left end - spin, scale, and move\n", " left_pin = obj.pin(obj.grab([-1, 0, 0]))\n", " left_pin.spin(\n", " axis=[1, 0, 0],\n", " angular_velocity=angular_vel,\n", " t_end=t_wait,\n", " ).scale(\n", " scale,\n", " 0.0,\n", " s_wait,\n", " center=[-x - half_length, -y, -z],\n", " ).move_by([move_delta, 0, 0], 0.0, t_end)\n", "\n", " # pin and animate right end - spin in opposite direction, scale, and move\n", " right_pin = obj.pin(obj.grab([1, 0, 0]))\n", " right_pin.spin(\n", " axis=[-1, 0, 0],\n", " angular_velocity=angular_vel,\n", " t_end=t_wait,\n", " ).scale(\n", " scale, 0.0, s_wait, center=[-x + half_length, -y, -z]\n", " ).move_by([-move_delta, 0, 0], 0.0, t_end)\n", "\n", " # add additional spinning motion\n", " angular_vel, t_end = 180, 150\n", "\n", " left_pin.spin(\n", " center=[-x, -y, -z],\n", " axis=[1, 0, 0],\n", " angular_velocity=angular_vel,\n", " t_start=t_wait,\n", " t_end=t_end,\n", " )\n", "\n", " right_pin.spin(\n", " center=[-x, -y, -z],\n", " axis=[-1, 0, 0],\n", " angular_velocity=angular_vel,\n", " t_start=t_wait,\n", " t_end=t_end,\n", " )\n", "\n", "# compile the scene and report stats\n", "scene = scene.build().report()\n", "\n", "# set preview options\n", "opts = {\"wireframe\": False}\n", "\n", "# preview the initial scene\n", "scene.preview(options=opts)" ] }, { "cell_type": "code", "execution_count": null, "id": "70ce60bb-552f-4d59-9116-1cdc805cbe5f", "metadata": {}, "outputs": [], "source": [ "# create a new session with the compiled scene\n", "session = app.session.create(scene)\n", "\n", "# set session params\n", "(\n", " session.param.set(\"auto-save\", 10)\n", " .set(\"dt\", 1 / 60)\n", " .set(\"frames\", 2400)\n", " .set(\"gravity\", [0, 0, 0])\n", " .set(\"csrmat-max-nnz\", 90000000)\n", " .set(\"keep-verts\", 100)\n", " .set(\"friction-mode\", \"max\")\n", ")\n", "\n", "# build this session\n", "session = session.build()" ] }, { "cell_type": "code", "execution_count": null, "id": "ab76b71d-6c12-486b-9ff0-f8713f96f0a7", "metadata": {}, "outputs": [], "source": [ "# start the simulation (this example takes a long time)\n", "session.start()" ] }, { "cell_type": "code", "execution_count": null, "id": "72e221cf-7458-4753-b3f2-3f9e273c7ee0", "metadata": {}, "outputs": [], "source": [ "# this example takes a long time...\n", "# in case you shutdown the server (or kernel) and still want to restart\n", "# from where you have (auto) saved, do this. Do not call cells above.\n", "\n", "from frontend import App # noqa\n", "\n", "# recover the session from auto-saved state\n", "session = App.recover(\"large-five-twist\")\n", "\n", "# resume if not currently running\n", "if not App.busy():\n", " session.resume()\n", "\n", "# preview the current state\n", "session.preview({\"wireframe\": False})\n", "\n", "# stream the logs\n", "session.stream()" ] } ], "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 }