{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "692919f7-7e12-4dff-8d94-3fe18a19b7c5", "metadata": {}, "outputs": [], "source": [ "# File: needle.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": "63f1d19d-48ee-499a-b2c3-dea19dbae0c3", "metadata": {}, "outputs": [], "source": [ "import random\n", "\n", "from frontend import App\n", "\n", "# create an app\n", "app = App.create(\"needle\")\n", "\n", "# create a square sheet mesh\n", "V, F = app.mesh.square(res=129)\n", "app.asset.add.tri(\"sheet\", V, F)\n", "\n", "# create a cone mesh to act as the needle\n", "V, F = app.mesh.cone(height=5, Nr=40, Ny=64, Nb=12, radius=1, sharpen=2)\n", "app.asset.add.tri(\"cone\", V, F)\n", "\n", "# create a sphere tetrahedral mesh as the weight\n", "V, F, T = app.mesh.icosphere(r=0.25, subdiv_count=4).tetrahedralize()\n", "app.asset.add.tet(\"sphere\", V, F, T)\n", "\n", "# create a scene\n", "scene = app.scene.create()\n", "\n", "# add cone needle pointing upward\n", "cone = scene.add(\"cone\")\n", "cone.at(0, -0.25, 0).scale(0.2).rotate(90, \"x\").pin()\n", "\n", "# add heavy sphere that will push sheets down onto needle\n", "sphere = scene.add(\"sphere\").at(0, 1, 0)\n", "sphere.param.set(\"density\", 1e5)\n", "sphere.pin().pull().unpin(1.0)\n", "\n", "# add multiple sheets stacked with rotation\n", "n, space = 5, 0.05\n", "for i in range(n):\n", " y = (i + 1) * space\n", " deg = i * 90 / n\n", " obj = scene.add(\"sheet\")\n", " obj.at(0, y, 0).rotate(90, \"x\").rotate(deg + 5 * random.random(), \"y\")\n", " obj.param.set(\"strain-limit\", 0.05).set(\"friction\", 0.5).set(\"young-mod\", 100).set(\"bend\", 1.0)\n", "\n", "# compile the scene and report stats\n", "scene = scene.build().report()\n", "\n", "# preview the initial scene\n", "scene.preview()" ] }, { "cell_type": "code", "execution_count": null, "id": "23b3ee6a-b63e-4435-a53f-80af5be235d8", "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\", 120).set(\"friction-mode\", \"max\")\n", "\n", "# build this session\n", "session = session.build()" ] }, { "cell_type": "code", "execution_count": null, "id": "32e7419c-d410-4ad8-8c3a-cb2bbd9db907", "metadata": {}, "outputs": [], "source": [ "# start the simulation and live-preview the results\n", "session.start().preview()\n", "\n", "# also show simulation logs in realtime\n", "session.stream()" ] }, { "cell_type": "code", "execution_count": null, "id": "495397b1-1cb4-45b1-af4d-eb56b44e415b", "metadata": {}, "outputs": [], "source": [ "# create an animation from the simulation results\n", "session.animate()" ] }, { "cell_type": "code", "execution_count": null, "id": "f53f2f7a-f8e3-4e47-b643-9b3b27c551b6", "metadata": {}, "outputs": [], "source": [ "# export the animation to file\n", "session.export.animation()" ] }, { "cell_type": "code", "execution_count": null, "id": "9fee8e48-5783-4e2a-bc49-4069a3a45e80", "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 }