Skip to content

feat(installer): Maya drag-and-drop installer - #12

Merged
891458249 merged 3 commits into
mainfrom
installer-maya-module-drag-drop
Apr 22, 2026
Merged

feat(installer): Maya drag-and-drop installer#12
891458249 merged 3 commits into
mainfrom
installer-maya-module-drag-drop

Conversation

@891458249

@891458249 891458249 commented Apr 21, 2026

Copy link
Copy Markdown
Owner

Summary

Companion to Slice 13 (PR #11, now merged) — a drag-and-drop installer so Maya artists can install / uninstall the rbfmax_maya plugin by dragging a single Python file into the Maya viewport.

This PR was originally planned to stack on the Slice 13 branch, but Slice 13 merged to main during preparation, so it is now a standard PR against main. Diff shows exactly 6 files / +769 lines — no Slice 13 content duplicated.

Design

  • Maya Module System (.mod file + standalone directory under ~/Documents/maya/modules/) rather than dropping .mll directly into the user's plug-ins dir. Benefits:
    • Clean uninstall — one .mod + one directory, both in user-owned paths (no admin privileges required)
    • Multi-version coexistence — a single install covers Maya 2022 + 2025 via MAYAVERSION blocks in the .mod file
  • onMayaDroppedPythonFile — Autodesk's standard drag-drop hook; stable across Maya 2022 / 2024 / 2025 / 2026
  • Per-version plug-in subdirsinstaller/plug-ins/2022/ and installer/plug-ins/2025/ (the .mll binaries themselves are gitignored; installer/package.py copies them from build-maya-<ver>/bin/Release/)
  • Scene node purge before unloadPlugin — uninstall deletes all mRBFNode + mRBFShape nodes first; Maya refuses unloadPlugin otherwise

Files

File Purpose
installer/drag_drop_install.py Drag-drop entry + install/uninstall logic (~400 LOC)
installer/package.py Copies built .mll from build-maya-<ver>/ with strict fail-fast guard
installer/README.md Chinese user guide (end-user + developer flows + troubleshooting)
docs/install.md Repository-level entry for Maya end users
README.md +5 lines: Quick Start blockquote pointing at docs/install.md
.gitignore +5 lines: exclude installer/plug-ins/*.mll (build artifacts)

Validation — mayapy install + uninstall cycle

Test Maya 2022 Maya 2025
package.py copies .mll ✓ 505.5 KiB ✓ 506.0 KiB
install copies payload
install writes .mod (dual-version blocks)
uninstall deletes .mod
uninstall deletes module dir
post-uninstall residue check zero zero
package.py build-missing guard exit 1 with full cmake recipe

Manual verification (pending, before merge)

  1. python installer/package.py on a dev machine with both builds fresh
  2. Drag installer/drag_drop_install.py into Maya 2022 GUI viewport → click "安装" → verify plugin loads and createNode mRBFNode + createNode mRBFShape succeed
  3. Drag the same file again → click "卸载" → verify no residue in ~/Documents/maya/modules/
  4. Repeat 2–3 on Maya 2025 GUI

Test plan

  • package.py strict guard — exit 1 when build missing, exit 0 + copies on all-present

  • Maya 2022 install via mayapy (writes .mod + payload)

  • Maya 2022 uninstall via mayapy (zero residue)

  • Maya 2025 install via mayapy (writes .mod + payload)

  • Maya 2025 uninstall via mayapy (zero residue)

  • GUI drag-drop install on Maya 2022 (user-side, before merge)

  • GUI drag-drop install on Maya 2025 (user-side, before merge)

  • Verified on Windows machine with HOME=Documents env var (reproduced double-Documents bug, confirmed fix produces single-Documents path via cmds.internalVar)

d891458249-rgb and others added 3 commits April 22, 2026 06:33
Companion to Slice 13 — lets end users install/uninstall the
rbfmax plugin by dragging a Python file into the Maya viewport.

Files added
-----------
- installer/drag_drop_install.py — onMayaDroppedPythonFile hook +
  install / uninstall via Maya Module System (.mod descriptor
  written into the user's ~/Documents/maya/modules).  Single-
  version install covers Maya 2022 and 2025 via per-version
  MAYAVERSION blocks in the .mod file.
- installer/package.py — copies built .mll from
  build-maya-<ver>/bin/Release/ into installer/plug-ins/<ver>/.
  Strict fail-fast build-missing preflight: exits 1 with a full
  cmake recipe if either version's .mll is absent.
- installer/README.md — Chinese user guide covering both the end-
  user and developer flows, plus a troubleshooting section.
- docs/install.md — repository-level user entry pointing at the
  installer (so GitHub viewers see the Maya install path without
  having to download the zip first).

Files updated
-------------
- README.md — adds a blockquote under Quick Start pointing
  Maya end users at docs/install.md.
- .gitignore — excludes installer/plug-ins/2022/*.mll and
  installer/plug-ins/2025/*.mll (large build artifacts; users
  populate them via package.py).

Validation
----------
mayapy install + uninstall smoke cycle on Maya 2022 and 2025:
- package.py copies .mll        : Maya 2022 505.5 KiB / 2025 506.0 KiB
- install copies payload + .mod : both versions OK
- uninstall deletes .mod + dir  : both versions OK
- post-uninstall residue check  : zero bytes on both versions
- build-missing guard           : exit 1 with full cmake recipe

Design rationale
----------------
- Maya Module System (rather than dropping .mll into the user's
  plug-ins dir) gives a clean uninstall surface — one .mod file +
  one directory, both in a user-owned, non-system path.
- onMayaDroppedPythonFile is Autodesk's standard drag-drop hook;
  stable across Maya 2022 / 2024 / 2025 / 2026.
- Per-version plug-in subdirectories are selected at Maya runtime
  via MAYAVERSION blocks in the .mod file — one install script
  covers all supported versions, no user choice needed.
- Scene node purge (deletes mRBFNode + mRBFShape) precedes
  unloadPlugin during uninstall; Maya refuses unload otherwise.

Stacked on top of Slice 13 — must merge after PR #11.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Windows machines with HOME env var set (Git Bash / MSYS / Cygwin /
WSL commonly set it to Documents), os.path.expanduser('~') returns
C:/Users/<user>/Documents instead of C:/Users/<user>, causing the
installer to write .mod file and module tree to
C:/Users/<user>/Documents/Documents/maya/modules/ — a path Maya never
scans. Installer reported success but plugin never loaded; createNode
fell back to unknown placeholder nodes.

Fix: use cmds.internalVar(userAppDir=True) when inside Maya (Maya uses
SHGetFolderPath independent of HOME env), and USERPROFILE as fallback
outside Maya on Windows (USERPROFILE is the Windows-standard variable
and never modified by Unix tools).

Discovered during Slice 13 GUI verification — user's HOME was set to
Documents by a prior Git Bash install; mayapy automated smokes did not
catch this because mayapy in CI-style setups typically runs with a
cleaner env.
On Windows, even after cmds.unloadPlugin('rbfmax_maya'), the .mll file
is held by Maya's DLL loader (FreeLibrary may defer). shutil.rmtree
fails with [WinError 5] Permission Denied. Prior to this fix,
reinstall flow threw a PermissionError that aborted _install, and
uninstall reported 'completed with warnings' while silently leaving
the .mll behind (misleading because autoload would still fire next
launch if .mod was recreated).

Changes:
- Add _safe_rmtree with retry+sleep (Windows DLL handle release lag)
- Add _force_overwrite_tree as file-level fallback when rmtree fails
- After unloadPlugin, gc.collect() + time.sleep(0.5) to encourage
  FreeLibrary completion
- _copy_payload falls back to file-level overwrite instead of aborting
- _uninstall dialog now distinguishes clean uninstall vs partial
  (with explicit 'restart Maya to finish cleanup' instruction)

Fundamental Windows limitation remains: fully hot reinstall (same
session, new .mll replacing locked .mll) is not achievable and not
attempted. Hot uninstall + cold reinstall (after Maya restart) is
the supported path.

Discovered during Slice 13 GUI verification when user reinstalled
in same session.
@891458249
891458249 merged commit 710e0f3 into main Apr 22, 2026
4 checks passed
@891458249
891458249 deleted the installer-maya-module-drag-drop branch April 22, 2026 03:11
891458249 added a commit that referenced this pull request Apr 23, 2026
* build(cmake): bump VERSION 1.1.0 -> 1.2.0 (Phase 2B close-out)

Phase 2B delivered Viewport 2.0 visualization (Slice 13 Path B),
HM-1 per-center viridis coloring (Slice 14), HM-2 prediction-field
grid + X-Ray (Slice 15), and a drag-drop installer (PR #12 with
two follow-ups).  No Phase 1 or Slice 10A/11/12 touches; Phase 2A
invariants preserved throughout.

Top-level CMakeLists.txt project VERSION bumps to 1.2.0.
maya_node/CMakeLists.txt RBFMAX_MAYA_PLUGIN_VERSION follows; this
value is injected into plugin_info.hpp via configure_file and bound
into the .mll via MFnPlugin::registerNode's 4th-arg version string.
Verified via mayapy: cmds.pluginInfo('rbfmax_maya', q=True,
version=True) returns '1.2.0' on both Maya 2022 and 2025 builds.

* docs(changelog): add [1.2.0] entry — HM-1 + HM-2 + X-Ray + installer

* docs(devlog): record Slice 16 — Phase 2B retrospective + v1.2.0

~145 LOC Slice 16 entry covering Phase 2B scope summary (5 PRs
merged), quantitative summary (LOC / tests / F-stops), invariant
tracking (Phase 1 / mRBFNode compute / mRBFShape R-44 / Slice 13
override config / Slice 14 viridis LUT — all zero-touch across
the phase), tech-debt status table (T-17/R-45 resolved within
Phase 2B; T-10/T-16/T-18/T-19/T-20 + dev_unload.py rolled to
Phase 2C), Phase 2B reviewer-discipline summary (Rules 3/4
exercised + Rule 5 formalization from Slice 13), Phase 2C entry
conditions (4 specific deliverables), Slice 16-specific
validation (139/180/8 smokes/version injection assertion),
post-merge tag plan (v1.1.0 retro on d624c79 + v1.2.0 on the
merge commit).

Also bumps README.md version badge to 1.2.0 (release link
reference).

---------

Co-authored-by: 891458249 <d891458249@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants