git.lucas.co / hou-control
SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git

commit5ed7cba84906c9b8b86c09274fc6a4ded0d7934d
parent5b26e8cd76
authorLucas Galante <[email protected]>
date2026-09-10 14:59
hc: track the agent bridge, reference docs and new HDAs; fix hrun paths

A handful of files that the tracked tree depends on were never committed.

houdini-agent/bridge.py was tracked but the wrapper that invokes it, hrun,
was not -- and hrun hardcoded /home/lsgalante/src/hou-control, which stopped
existing when the repo moved under Dropbox, so it pointed at nothing. It now
derives both the bridge path and the venv interpreter from its own location,
and says how to create the venv when it is missing instead of failing with a
bare "no such file". hou_geo.py, which imports run_in_houdini from bridge,
is tracked alongside it.

houdini-agent/mcpserver/requirements.txt is the same file the previous commit
deleted at mcpserver/requirements.txt, so that commit left a tracked MCP
server with untracked dependencies. Tracked here.

The previous commit also deleted notes/ without tracking the rewritten
replacements sitting at the repo root: developer.md, gem.md,
systems-theory.md, sop-verbs-reference.md and network-editor-prefs-
reference.md. These are rewrites rather than moves -- shorter, and in two
cases sharing almost no wording with what they replace -- so the old
versions stay in history and these become the versioned copies going
forward. notes/GEM production notes.md still has no successor.

Four im_* HDAs were untracked among 117 tracked ones: im_endpoints,
im_midpoint, im_vdb_visualize_intersections, and im_soft_transform.1.1
(whose .1.0 is tracked and was modified last commit). The timestamped
.hdalc.bak.* files beside them are scratch -- .gitignore only covered
otls/backup as a directory, so it now ignores that suffix too.

agent_tests/.gitignore is the keep-the-directory pattern GEMINI.md relies on.

CLAUDE.md documents hrun, which had been the only way to poke at a live
session and lost its last mention when the SelectionDialog note was rewritten.

Co-Authored-By: Claude Opus 5 <[email protected]>

 .gitignore                                         |   1 +
 CLAUDE.md                                          |  14 +
 developer.md                                       | 139 ++++++++
 gem.md                                             |  54 ++++
 houdini-agent/agent_tests/.gitignore               |   2 +
 houdini-agent/hou_geo.py                           |  87 +++++
 houdini-agent/hrun                                 |  31 ++
 houdini-agent/mcpserver/requirements.txt           |   2 +
 network-editor-prefs-reference.md                  | 110 +++++++
 otls/sop_lsgalante.im_endpoints.1.0.hdalc          | Bin 0 -> 7605 bytes
 otls/sop_lsgalante.im_midpoint.1.0.hdalc           | Bin 0 -> 5675 bytes
 otls/sop_lsgalante.im_soft_transform.1.1.hdalc     | Bin 0 -> 10903 bytes
 ...alante.im_vdb_visualize_intersections.1.0.hdalc | Bin 0 -> 8723 bytes
 sop-verbs-reference.md                             | 349 +++++++++++++++++++++
 systems-theory.md                                  |  15 +
 15 files changed, 804 insertions(+)

diff --git a/.gitignore b/.gitignore
index 80aa499..aea9eb7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
 *.DS_Store
 *otls/backup
 .codex
+*.hdalc.bak.*
diff --git a/CLAUDE.md b/CLAUDE.md
index 5e9bc01..7561e9a 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -13,6 +13,20 @@ and exercises the settings merge, the `replaceNode` rewire and the node grid
 snap. It cannot cover anything needing `hou.ui` or a live pane — that still has
 to be driven by hand in Houdini.
 
+To drive a *running* Houdini from outside it, use `houdini-agent/hrun`, which
+pipes a snippet through `houdini-agent/bridge.py` to the `hrpyc` server that
+`uiready.py` starts on port 18811:
+
+```
+houdini-agent/hrun 'hou.node("/obj").children()'
+```
+
+It needs `houdini-agent/.venv` (`python3 -m venv`, then
+`pip install -r houdini-agent/mcpserver/requirements.txt`) and tells you so if
+it is missing. Anything it evaluates is marshalled onto Houdini's main thread
+by `hc.hcmainthread` — HOM is not thread-safe and rpyc answers on a connection
+thread.
+
 Everything runs inside Houdini's embedded Python 3.13. To exercise changes, reload from within Houdini:
 - From the `hc` main menu: **Reload Hotkeys**, **Reload Colors**, **Reload Keycam**.
 - Full package reload: `hou.ui.reloadPackage(...)` (see `HCSession.reloadHC`).
diff --git a/developer.md b/developer.md
new file mode 100644
index 0000000..7f2ce21
--- /dev/null
+++ b/developer.md
@@ -0,0 +1,139 @@
+# Shapeshifter - Developer Plugin Design Document
+
+Version 0.1 | Author: Lucas Galante | December 2025
+
+## Overview
+
+Developer operators combined in SOP solver and DOP contexts in Houdini. Creating lifelike elements in digital containers.
+
+## Data Types
+
+### 1. Live Data
+Fluid data which runs like a stream through the simulation.
+
+### 2. Derivative Data
+Data calculated anew every frame based on live data.
+
+## Regions
+
+After making the GEM mold operators, there is more experience with treating a model as a composite of distinct parts and overlapping attributes. Regions in a model are like organs -- they fit together physically and programmatically.
+
+Living models host mechanisms which influence their status. Morphogen gradients demonstrate how distribution of matter on one scale can influence form on another scale.
+
+A living model's boundaries are predictable before they exist -- they require an environment supplying real elements, but information about where those elements will go is present ahead of time.
+
+## Operator Categories
+
+### Pre-Simulation
+The embryo or seed is created. Initial selections, value assignments, and attributes are introduced. Sets the characteristics and landscape of the simulation before it runs.
+
+### Simulation Attribute Operators
+Operate on simulation attributes that persist from the end of one frame to the beginning of another.
+
+### Development Attribute Operators
+Composite simulation attributes into development attributes. Development attributes are cleared each frame and must be reconstructed. They tell the surface development operators how the surface will change.
+
+### Surface Development Operators
+Read development attributes and use that information to transform the mesh or volume. Position and normal are changed; other attributes are untouched.
+
+### Meshing Operators
+Adjust topology of geometry to keep primitives and points proportional to surface area.
+
+## Geometry Classes
+
+### Points
+The majority of nodes operate on point attributes. The keystone is the develop and remesh node pair.
+
+### Vertices
+No well-defined use cases yet.
+
+### Primitives
+Waiting for a clear use case.
+
+### Detail
+Global attributes useful for storing statistics and analyses.
+
+## Attribute Categories
+
+### Scalar
+Operators that edit scalar attribute values.
+
+### Vector
+Operators that edit vector attribute values.
+
+### Surface
+Operators that use input attributes to alter geometry topology.
+
+### Volume
+Operators that modify volumes in tandem with mesh geometry. Not yet fleshed out.
+
+Looking ahead: Volumes can be reservoirs of value. Vector directs value to flow inside geometry (Shapeshifter Core) or away from the surface (Shapeshifter Miasma).
+
+## Operators
+
+### Scalar
+- Scalar Analysis
+- Scalar Composite
+- Scalar Combine
+- Scalar Concentrate
+- Scalar Diffuse
+- Scalar Initialize
+- Scalar Map
+- Scalar Migrate
+- Scalar Normalize
+- Scalar Ramp
+- Scalar Weight
+
+### Vector
+- Vector Analysis
+- Vector Composite
+- Vector Conform
+- Vector Diffuse
+- Vector Direct
+- Vector From Scalar
+- Vector Migrate
+- Vector Normalize
+- Vector Rotate
+- Vector Unify
+- Vector Weight
+
+### Surface
+- Surface Adapt
+- Surface Open
+- Surface Suture
+- Subdivide
+- Remesh
+- Detangle
+
+### Time
+- Time
+- Time Ramp
+- Time Switch
+
+### Simulation
+- Solver
+- Develop
+- Submute Begin / End
+- Lead
+
+### Tentative
+- Region
+- Analyze
+- Vitality
+- Edge Analysis
+- Analyze Change
+- Volume/Miasma
+- Volume/Core
+- Filter/Select
+- Region/Region Center
+- Attribute/Promote
+- Visualize/Panel
+- ID
+- Age/Expire
+- Energize
+- Create/Embryo
+- Filter/Cull
+- Combine
+- Constant
+- Measure
+- Metamax
diff --git a/gem.md b/gem.md
new file mode 100644
index 0000000..62a9c06
--- /dev/null
+++ b/gem.md
@@ -0,0 +1,54 @@
+# GEM - General Export Methods
+
+Tools for getting things out of the computer.
+
+## Operators
+
+- GEM Build Area
+- GEM Flange Monoid
+- GEM Halo Merge
+- GEM Mold Flange
+- GEM Mold Preprocess
+- GEM Mold Shell
+- GEM Mold Solver
+- GEM Mold Structure
+- GEM Orient
+- GEM Partition
+
+## Moldtek Partition Viewer State
+
+Modes:
+- Add/remove
+- Edit
+
+Operations:
+- Add new partition
+- Add first prim to partition
+- Add additional prims to partition
+- Remove prim from partition
+- Remove final prim from partition
+- Remove partition
+- Change draft angle for partition globally
+- Change draft angle for partition locally
+- Change reach of partition globally
+- Change reach of partition locally
+- Transfer prim to different partition
+- Merge partitions
+- Split partition
+
+## Production Notes (June 2024)
+
+### Scale
+Used a 1 mm:1 unit equivalency. The scale is very broad and numbers become arbitrarily large. 1 cm:1 unit scale would be better for future work.
+
+### GEM Mold Shell
+Critical parameter is the thickness range. Must be thick enough to print and maintain rigidity, thin enough to remove post-resin cure.
+
+Good parameters from the original cast:
+- Maximum Thickness: 0.75 (mm/units)
+- Minimum Thickness: 0.6 (mm/units)
+- Remesh Division Size: 0.9
+- Ramp: Linear
+
+### UV Curing
+Using a Peopoly Phenom curing box, default settings for 3-6 minutes. Interval curing (5 min) would be better.
diff --git a/houdini-agent/agent_tests/.gitignore b/houdini-agent/agent_tests/.gitignore
new file mode 100644
index 0000000..120f485
--- /dev/null
+++ b/houdini-agent/agent_tests/.gitignore
@@ -0,0 +1,2 @@
+*
+!/.gitignore
diff --git a/houdini-agent/hou_geo.py b/houdini-agent/hou_geo.py
new file mode 100644
index 0000000..9873442
--- /dev/null
+++ b/houdini-agent/hou_geo.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+import sys
+from bridge import run_in_houdini
+
+def get_grid_spacing():
+    try:
+        code = "hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor).getPrefs()"
+        import ast
+        res = run_in_houdini(code)
+        if "=>" in res:
+            res = res.split("=>", 1)[1].strip()
+        prefs = ast.literal_eval(res)
+        return float(prefs.get('gridxstep', 2.0)), float(prefs.get('gridystep', 1.0))
+    except Exception:
+        return 2.0, 1.0
+
+def move_node(node_path, x, y):
+    gx, gy = get_grid_spacing()
+    snapped_x = round(float(x) / gx) * gx
+    snapped_y = round(float(y) / gy) * gy
+    
+    code = f"""
+n = hou.node({repr(node_path)})
+if n:
+    parent = n.parent()
+    target_pos = hou.Vector2({snapped_x}, {snapped_y})
+    
+    # Check for conflict
+    for sibling in parent.children():
+        if sibling != n and sibling.position().distanceTo(target_pos) < 0.1:
+            # Shift conflicting neighbor to the right
+            sibling.move(hou.Vector2({gx}, 0))
+            
+    n.setPosition(target_pos)
+"""
+    return run_in_houdini(code)
+
+def create_node(type_name, name=None, parent="/obj", input_node=None):
+    gx, gy = get_grid_spacing()
+    code = f"""
+p = hou.node('{parent}')
+n = p.createNode('{type_name}', node_name={repr(name)} if {repr(name)} else None)
+if {repr(input_node)}:
+    in_node = hou.node({repr(input_node)})
+    if in_node:
+        n.setInput(0, in_node)
+print(n.path())
+"""
+    res = run_in_houdini(code)
+    # Extract path from stdout or result_repr
+    node_path = res.strip()
+    if "=>" in node_path:
+        node_path = node_path.split("=>", 1)[0].strip()
+    if not node_path.startswith("/"):
+        # fallback
+        node_path = f"{parent}/{name}"
+        
+    if input_node:
+        try:
+            res_pos = run_in_houdini(f"print(tuple(hou.node('{input_node}').position()))")
+            pos_str = res_pos.split("=>", 1)[0].strip()
+            import ast
+            ix, iy = ast.literal_eval(pos_str)
+            move_node(node_path, ix, iy - gy)
+        except Exception: pass
+    else:
+        move_node(node_path, 0, 0)
+    return node_path
+
+def create_color_node(name, parent, input_node, color=(1, 0, 0)):
+    c_path = create_node("color", name, parent, input_node)
+    run_in_houdini(f"hou.node('{c_path}').parm('colorr').set({color[0]})")
+    run_in_houdini(f"hou.node('{c_path}').parm('colorg').set({color[1]})")
+    run_in_houdini(f"hou.node('{c_path}').parm('colorb').set({color[2]})")
+    return c_path
+
+if __name__ == "__main__":
+    if len(sys.argv) < 2: sys.exit(1)
+    cmd = sys.argv[1]
+    if cmd == "create":
+        print(create_node(sys.argv[2], sys.argv[3] if len(sys.argv) > 3 else None, sys.argv[4] if len(sys.argv) > 4 else "/obj", sys.argv[5] if len(sys.argv) > 5 else None))
+    elif cmd == "move":
+        print(move_node(sys.argv[2], sys.argv[3], sys.argv[4]))
+    elif cmd == "ls":
+        print(run_in_houdini(f"print([n.name() for n in hou.node('{sys.argv[2] if len(sys.argv) > 2 else '/obj'}').children()])"))
+    elif cmd == "delete":
+        print(run_in_houdini(f"n = hou.node('{sys.argv[2]}'); n.destroy() if n else None"))
diff --git a/houdini-agent/hrun b/houdini-agent/hrun
new file mode 100755
index 0000000..f6a29bc
--- /dev/null
+++ b/houdini-agent/hrun
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Wrapper to run python code in a running Houdini via the hrpyc bridge.
+#
+# Paths are derived from this script's own location. The previous version
+# hardcoded /home/lsgalante/src/hou-control, which stopped existing when the
+# repo moved under Dropbox, so hrun silently pointed at nothing.
+set -euo pipefail
+
+AGENT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
+BRIDGE_SCRIPT="$AGENT_DIR/bridge.py"
+VENV_PY="$AGENT_DIR/.venv/bin/python3"
+
+if [ "$#" -lt 1 ]; then
+    echo "Usage: hrun <python_code>" >&2
+    exit 1
+fi
+
+if [ ! -x "$VENV_PY" ]; then
+    echo "hrun: no interpreter at $VENV_PY" >&2
+    echo "      python3 -m venv '$AGENT_DIR/.venv'" >&2
+    echo "      '$AGENT_DIR/.venv/bin/pip' install -r '$AGENT_DIR/mcpserver/requirements.txt'" >&2
+    exit 1
+fi
+
+if [ ! -f "$BRIDGE_SCRIPT" ]; then
+    echo "hrun: bridge not found at $BRIDGE_SCRIPT" >&2
+    exit 1
+fi
+
+# Pass the original string argument as is.
+exec "$VENV_PY" "$BRIDGE_SCRIPT" "$1"
diff --git a/houdini-agent/mcpserver/requirements.txt b/houdini-agent/mcpserver/requirements.txt
new file mode 100644
index 0000000..84b85ea
--- /dev/null
+++ b/houdini-agent/mcpserver/requirements.txt
@@ -0,0 +1,2 @@
+mcp>=1.0
+rpyc>=4.1,<5
diff --git a/network-editor-prefs-reference.md b/network-editor-prefs-reference.md
new file mode 100644
index 0000000..a526614
--- /dev/null
+++ b/network-editor-prefs-reference.md
@@ -0,0 +1,110 @@
+# Network Editor Settings Reference
+
+Raw dump of all network editor preferences from Houdini 21. Useful for looking up pref names and default values.
+
+```
+allowdiveintohdas: '1'
+allowdroponwire: '1'
+autoscroll: '1'
+backgroundimagebrightness: '1.0'
+backgroundimageediting: '0'
+badge64bit: normal
+badgeLoadFromDisk: large
+badgeNodeDiveable: normal
+badgechilderror: large
+badgecomment: normal
+badgeconstraints: normal
+badgedynamictop: normal
+badgeerror: large
+badgehastakedata: hide
+badgehdadelaysync: normal
+badgehdalocked: normal
+badgehdaunlocked: normal
+badgekinematics: hide
+badgelopdebug: normal
+badgeloppopulationmask: normal
+badgelopunloadedpayloads: normal
+badgemessage: normal
+badgemqclientsauth: normal
+badgemqserverauth: normal
+badgeneedscook: hide
+badgenodehasdata: hide
+badgenodelocked: normal
+badgenodeunload: normal
+badgenotcompilable: normal
+badgetimedep: normal
+badgevexcache: normal
+badgewarning: normal
+connectorsnapradius: 0.700000
+copypathstoclipboard: '1'
+dimunusednodes: '0'
+distancefordrag: 0.050000
+doautomovenodes: '0'
+dosnapping: '1'
+flagsallowpreselect: '1'
+gridmode: '2'
+gridsnapping: '1'
+gridxstep: '2.0'
+gridystep: '1.0'
+grouplistsplit: 0.75
+listmode: '0'
+maxflyoutscale: 10000.000000
+maxnameheight: 0.000000
+maxnamewidth: 10000.000000
+maxtaskgraphdepth: '0'
+maxtaskgraphrows: '20'
+maxworkitemsperrow: '10'
+minnameheight: 0.000000
+overviewmode: '2'
+palettemode: '0'
+palettesize: 225 225
+perfstatname: Time
+shakesensitivity: 1.000000
+showanimations: '1'
+showcancelledworkitems: '1'
+showchilddep: '1'
+showcookedworkitems: '1'
+showcookingworkitems: '1'
+showdep: '0'
+showdirtyworkitems: '1'
+showfailedworkitems: '1'
+showgrouplist: '0'
+showloplayercolor: '1'
+showmenu: '0'
+shownodeshapes: '1'
+shownodetypes: '1'
+showparmdialog: '0'
+showparmdialogmax: '1'
+showpartitionworkitems: '1'
+showperfstats: '1'
+showpreviews: '1'
+showprompttext: '1'
+showsimpleshape: '0'
+showspareinputdep: '1'
+showstackedlook: '1'
+showstaticworkitems: '1'
+showtaskgraph: '1'
+showtaskgraphperf: '0'
+showtasksmenu: '1'
+showtree: '0'
+showtypesidebar: '0'
+showvopinoutlabels: '0'
+snapradius: 0.100000
+solohighlightedworkitems: '0'
+taskgraphcollapsemode: Off
+taskgraphperfstatname: Cook Time
+taskgraphsortcriteria: Automatic
+taskgraphsortdirection: '0'
+textbadgecomment: truncated
+textbadgecontextoptiondeps: selected_full
+textbadgedescriptiveparm: truncated
+textbadgedetailid: hide
+textbadgelayercount: truncated
+textbadgeloplastmodifiedprim: truncated
+textbadgeoutputforview: truncated
+transientinfo: '1'
+treesplit: 0.25
+typesidebarsplit: 0.25
+useworkitemcolorattribute: '0'
+wirefadefactor: 1.000000
+```
diff --git a/otls/sop_lsgalante.im_endpoints.1.0.hdalc b/otls/sop_lsgalante.im_endpoints.1.0.hdalc
new file mode 100644
index 0000000..da69836
Binary files /dev/null and b/otls/sop_lsgalante.im_endpoints.1.0.hdalc differ
diff --git a/otls/sop_lsgalante.im_midpoint.1.0.hdalc b/otls/sop_lsgalante.im_midpoint.1.0.hdalc
new file mode 100644
index 0000000..d733c8f
Binary files /dev/null and b/otls/sop_lsgalante.im_midpoint.1.0.hdalc differ
diff --git a/otls/sop_lsgalante.im_soft_transform.1.1.hdalc b/otls/sop_lsgalante.im_soft_transform.1.1.hdalc
new file mode 100644
index 0000000..9ca0d13
Binary files /dev/null and b/otls/sop_lsgalante.im_soft_transform.1.1.hdalc differ
diff --git a/otls/sop_lsgalante.im_vdb_visualize_intersections.1.0.hdalc b/otls/sop_lsgalante.im_vdb_visualize_intersections.1.0.hdalc
new file mode 100644
index 0000000..3ed532c
Binary files /dev/null and b/otls/sop_lsgalante.im_vdb_visualize_intersections.1.0.hdalc differ
diff --git a/sop-verbs-reference.md b/sop-verbs-reference.md
new file mode 100644
index 0000000..8cf59d1
--- /dev/null
+++ b/sop-verbs-reference.md
@@ -0,0 +1,349 @@
+# SOP Verbs Reference
+
+Raw dump of available `hou.SopVerb` names from Houdini 21. Includes VDB and volume verbs.
+
+```
+add
+agentlayer::2.0
+agentunpack
+apex::invokegraph
+attribcast
+attribcombine
+attribcomposite
+attribcopy
+attribcreate::2.0
+attribfill
+attribfromparm
+attribfromvolume
+attribinterpolate
+attribmirror
+attribpromote
+attribreorient
+attribstringedit
+attribswap
+attribtransfer
+attribute
+attribvop
+basis
+blast
+blendshapes
+blendshapes::2.0
+bonecapturebiharmonic
+bonedeform
+boolean::2.0
+bound
+box
+cache
+cacheif
+cap
+captureattribpack
+captureattribunpack
+capturepaintcore
+carve
+circle
+circlefromedges
+clip
+clip::2.0
+cluster
+clustermesh
+connectivity
+control
+convert
+convertvdb
+convertvdbpoints
+convertvolume
+convexdecomposition
+cop2net
+copytopoints
+copytopoints::2.0
+copyxform
+crease
+crowdmotionpathavoidcore
+crowdmotionpatheditcore
+crowdmotionpathevaluatecore
+curve
+curvesect
+delete
+deltamush
+detangle
+dissolve::2.0
+divide
+dopimport::2.0
+edgecollapse
+edgecusp
+edgedivide
+edgeequalize
+edgeflip
+edgestraighten
+edgetransport
+edgecollapse
+ends
+enumerate
+error
+extractcentroid
+extracttransform
+facet
+featherattribinterpolate
+featherbarbtangents
+featherray
+feathertemplateinterpolatecore
+file
+fit
+font
+fractal
+fuse
+fuse::2.0
+grid
+groupcombine
+groupcopy
+groupcreate
+groupdelete
+groupexpand
+groupfindpath
+groupinvert
+grouppromote
+grouprange
+grouprename
+groupsfromname
+grouptransfer
+guidegroomcore
+guidemask
+guideprocesscore
+hairclump
+hairgencore
+heatgeodesic
+hole
+inflate
+intersectionanalysis
+intersectionstitch
+invoke
+invokegraph
+isooffset
+join
+kinefx::agentfromrigcore
+kinefx::attribtransformcompute
+kinefx::attribtransformextract
+kinefx::characterblendshapesadd
+kinefx::characterblendshapescore
+kinefx::computemotionclipcreate
+kinefx::computemotionclipretime
+kinefx::computerigpose
+kinefx::computetransform
+kinefx::configurerigvis::2.0
+kinefx::extractrotationalmomentum
+kinefx::ikchains::2.0
+kinefx::motionclipextractkeyposes
+kinefx::motionclipmerge
+kinefx::motionclipposedelete::2.0
+kinefx::motionclipunpack
+kinefx::motionclipupdate
+kinefx::motionmixer
+kinefx::pendulummotioncore
+kinefx::poseweightinterp
+kinefx::projectilemotioncore
+kinefx::resamplesplinetransforms
+kinefx::rigattribvop
+kinefx::rotatebymomentum
+kinefx::skeletonblend::2.0
+kinefx::skeletonblend::3.0
+kinefx::smoothmotioncore
+kinefx::usdanimimport
+kinefx::usdskinimport
+knife
+lidarimport
+line
+linearsolver
+lopimport::2.0
+matchtopology
+material
+measure
+measure::2.0
+merge
+mergepacked
+mirror
+mlexamplecreatecore
+mlexampledecomposecore
+mlexampledeserializepacked
+mlexampledeserializepoint
+mlexampleserializepacked
+mlexampleserializepoint
+mlregressioninferencecore
+mlregressionproximitycore
+name
+neighborsearchcl
+normal
+null
+onnx
+opencl
+orientalongcurve
+output
+pack
+packededit
+packfolder
+packinject
+packpoints
+pca
+peak
+pointcapturecore
+pointcloudnormal
+pointcloudreduce
+pointcloudsurface
+pointgenerate
+polybevel::3.0
+polycut
+polydoctor
+polyexpand2d
+polyextrude::2.0
+polyfill
+polyframe
+polypatch
+polyreduce::2.0
+polysoup
+polysplit::2.0
+polywire
+primitive
+primitivesplit
+quadremesh
+rawimport
+ray
+refine
+relax
+remesh
+remesh::2.0
+repack
+resample
+rest
+reverse
+revolve
+rewire
+sblend
+sblend::2.0
+scatter::2.0
+shapediff
+shrinkwrap::2.0
+simplexrefine
+skin
+smooth::2.0
+softpeak
+softxform
+solidify
+sort
+sphere
+splitpoints
+stash
+subdivide
+surfacesplat
+sweep::2.0
+switch
+switchif
+tangentfield
+tetcraft
+tetlayer
+tetpartition
+tetrahedralize
+tetrasurface
+texture
+texturefeature
+textureopticalflow
+topnetsop
+topotransfer
+torus
+trace
+triangulate2d::2.0
+triangulate2d::3.0
+tribez
+tridivide
+tristrip
+tube
+unpack
+unpackfolder
+unpackpoints
+unpackusd::2.0
+uvautoseam
+uvflatten::2.0
+uvflatten::3.0
+uvlayout::2.0
+uvlayout::3.0
+uvproject
+uvrelax
+uvtransform::2.0
+uvunwrap
+vdb
+vdbactivate
+vdbactivatesdf
+vdbadvectpoints
+vdbadvectsdf
+vdbanalysis
+vdbclip
+vdbcombine
+vdbconvexclipsdf
+vdbcreatecl
+vdbdiagnostics
+vdbextrapolate
+vdbfracture
+vdbfromparticles
+vdbfrompolygons
+vdblod
+vdbmerge
+vdbmorphsdf
+vdbocclusionmask
+vdbpointsdelete
+vdbpointsgroup
+vdbpotentialflow
+vdbprojectnondivergent
+vdbrenormalizesdf
+vdbresample
+vdbreshapesdf
+vdbsegmentbyconnectivity
+vdbsmooth
+vdbsmoothsdf
+vdbtopologytosdf
+vdbtospheres
+vdbvectormerge
+vdbvectorsplit
+vdbvisualizetree
+vertexsplit
+visibility
+volume
+volumeambientocclusion
+volumeanalysis
+volumearrivaltime
+volumebin
+volumeblur
+volumebound
+volumebreak
+volumecombine
+volumecompress
+volumeconvolve3
+volumefeather
+volumefft
+volumefromattrib
+volumemerge
+volumemix
+volumenormalize
+volumeopticalflow
+volumepatch
+volumerasterizelattice
+volumerasterizeparticles
+volumereduce
+volumeresample
+volumeresize
+volumesdf
+volumeslice
+volumesplice
+volumetrail
+volumevectorjoin
+volumevectorsplit
+volumevisualization
+volumevop
+voronoisplit
+watershed
+weightarraybiharmonic
+weightarrayinterpolate
+windingnumber
+wire
+wireblend
+xform
+xformaxis
+xformbyattrib
+```
diff --git a/systems-theory.md b/systems-theory.md
new file mode 100644
index 0000000..4e6e807
--- /dev/null
+++ b/systems-theory.md
@@ -0,0 +1,15 @@
+# Systems Theory Notes
+
+Processing feedback in dynamic systems.
+
+In a dynamic system or simulation, variables inform the procession of model states as the variables themselves develop. If the volume of an expanding object has an inverse correlation with its growth rate, the growth rate slows as the object grows.
+
+Macro-organs like blood vessels seem simple compared to their micro-counterparts. On small scales, chemical reactions destroy, alter and create themselves constantly. The behavior of macro organs is the effect of this unseen behavior.
+
+A fluid transportation system has two aspects: its purpose and its health. In biology, it is not really possible to determine the purpose of a strategy outside the context of the maintenance of the things which are doing things.
+
+Entity-hood is a discernible quality of systems and things: a cell and a cell wall, a walled city and the land around it.
+
+Defining the behavior of a simulated dynamical system requires partitioning information commensurate with what the system should clarify. To be effective, a model must predict the summation of behavior at a smaller scale. If the behavior of groups of actors is predictable, a model can be made ("emergent behavior").
+
+Tissue growth relies on principles which yield observable results, without necessarily reproducing the actual chemical dynamics. Cells multiply and are arranged to form tissue. The substance of tissue is a product of a metabolism, which is a system not unlike an aqueduct.