{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "17d3fb70-7402-4baa-9036-0db20acf45e0", "metadata": {}, "outputs": [], "source": [ "# File: codim.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": "71465ca9-adfd-45d5-a552-c75d7a1b3c4a", "metadata": {}, "outputs": [], "source": [ "from frontend import App\n", "\n", "# create an app\n", "app = App.create(\"codim\")\n", "\n", "# create an armadillo tetrahedral mesh\n", "V, F, T = app.mesh.preset(\"armadillo\").decimate(30000).tetrahedralize().normalize()\n", "app.asset.add.tet(\"armadillo\", V, F, T)\n", "\n", "# create a 1D rod strand mesh\n", "V, E = app.mesh.line([0, 0, -1], [0, 0, 1], 64)\n", "app.asset.add.rod(\"strand\", V, E)\n", "\n", "# create a scene\n", "scene = app.scene.create()\n", "\n", "# stack multiple armadillos vertically with spacing\n", "space = 0.9\n", "for k in range(3):\n", " armadillo = scene.add(\"armadillo\").scale(0.75).rotate(180, \"y\")\n", " armadillo.at(0, 0.75 + space * k, 0).jitter()\n", " armadillo.param.set(\"young-mod\", 2000)\n", "\n", "# add a curtain of vertical strands\n", "N = 21\n", "for i in range(N):\n", " x = (i - N // 2) / (N // 2)\n", " strand = scene.add(\"strand\").at(x, 0, 0)\n", " strand.param.set(\"young-mod\", 1e7).set(\"friction\", 0.5)\n", " # pin top and bottom of each strand\n", " strand.pin(strand.grab([0, 0, -1]) + strand.grab([0, 0, 1]))\n", "\n", "# add invisible walls to contain the simulation\n", "gap = 0.025\n", "scene.add.invisible.wall([1 + gap, 0, 0], [-1, 0, 0])\n", "scene.add.invisible.wall([-1 - gap, 0, 0], [1, 0, 0])\n", "scene.add.invisible.wall([0, 0, 1 + gap], [0, 0, -1])\n", "scene.add.invisible.wall([0, 0, -1 - gap], [0, 0, 1])\n", "\n", "# set preview options\n", "opts = {\"lookat\": [0, 0.8, 0], \"eye\": [0, 0.2, 2.5], \"fov\": 50}\n", "\n", "# compile the scene and report stats\n", "scene = scene.build().report()\n", "\n", "# preview the initial scene\n", "scene.preview(options=opts)" ] }, { "cell_type": "code", "execution_count": null, "id": "87be4a90-f981-472c-b892-388cb8caff97", "metadata": {}, "outputs": [], "source": [ "# create a new session with the compiled scene\n", "session = app.session.create(scene)\n", "\n", "# set session parameters\n", "session.param.set(\"frames\", 240).set(\"friction-mode\", \"max\")\n", "\n", "# build this session\n", "session = session.build()" ] }, { "cell_type": "code", "execution_count": null, "id": "0e6d83d6-dabe-4718-86a0-75a6f6a9f143", "metadata": {}, "outputs": [], "source": [ "# start the simulation and live-preview the results\n", "session.start().preview(options=opts)\n", "\n", "# also show simulation logs in realtime\n", "session.stream()" ] }, { "cell_type": "code", "execution_count": null, "id": "10e0527d-f3ce-4f14-8176-d103dd028970", "metadata": {}, "outputs": [], "source": [ "# create an animation from the simulation results\n", "session.animate(options=opts)" ] }, { "cell_type": "code", "execution_count": null, "id": "31c9b4c0-59f7-4205-a859-9bbd067d3fe6", "metadata": {}, "outputs": [], "source": [ "# export the animation to file and clear temp files\n", "session.export.animation(clear=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "05657fef-b410-43ea-8992-1d9e903fe6de", "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 }