Skip to content

Commit

Permalink
Merge pull request #7 from tbttfox/tyler/easy-installer
Browse files Browse the repository at this point in the history
Tyler/easy installer
  • Loading branch information
tbttfox authored Mar 12, 2024
2 parents b932f09 + 639a23e commit 1c1687a
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 6 deletions.
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,39 @@ As long as your package supports Plugins, Python, and Qt (or PySide), you can us
* In the future, I *do* have ideas for building an interface to an advanced deformer for dynamically previewing arbitrary splits, but the final output will always have the ability to bake down to a basic blendshape.

### Basic Usage
Follow this youtube link to a basic walkthrough of Simplex usage. This video highlights an older version of Simplex, but the interaction remains basically the same. [https://www.youtube.com/watch?v=LQwzsxU8z_Q](https://www.youtube.com/watch?v=LQwzsxU8z_Q)
Follow this youtube link to a basic walkthrough of Simplex usage. This video highlights a slightly older version of Simplex, but the interaction remains basically the same. [https://www.youtube.com/watch?v=LQwzsxU8z_Q](https://www.youtube.com/watch?v=LQwzsxU8z_Q)

## INSTALLATION

1. Download the latest release
2. Copy the `modules` folder from the zip file into your maya directory. On windows, that would mean copying into `%USERPROFILE%\Documents\maya` so that the module file sits at `%USERPROFILE%\Documents\maya\modules\simplex.mod`
3. Install numpy for mayapy [using pip](https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2022/ENU/Maya-Scripting/files/GUID-72A245EC-CDB4-46AB-BEE0-4BBBF9791627-htm.html). If you're using a Maya with Python 3, you should just be able to install numpy. For Python 2 on Windows, you'll have to find a .whl file compiled for your version. I'm not sure about Mac or Linux for Py2.
4. Run these two Python commands in Maya to start the tool. (This is probably what you should put into a shelf button)
## Easy Installation
1. Download [this file](https://raw.githubusercontent.com/blurstudio/Simplex/master/simplex_maya_installer.py) to your computer. Make sure it's saved as a python file.
2. Drag/drop the python file into a freshly opened instance of Maya (make sure all other mayas are closed). A command prompt window may open for a couple seconds. This is normal.
3. If you have multiple Maya versions installed, repeat step 2 for those versions as well. This just ensures that numpy is installed for those versions.
4. Create a python shelf button with this script.
```python
from simplexui import runSimplexUI
runSimplexUI()
```

## Updating
1. Download [this file](https://raw.githubusercontent.com/blurstudio/Simplex/master/simplex_maya_installer.py) to your computer. Make sure it's saved as a python file.
2. Drag/drop the python file into a freshly opened instance of Maya (make sure all other mayas are closed). A command prompt window may open for a couple seconds. This is normal.
3. If you have multiple Maya versions installed, you do NOT have to repeat step 2 for all of them.


## Manual Installation
1. Download the `simplex-v*.*.*.zip` file from the [latest release](https://github.com/blurstudio/Simplex/releases/latest)
2. Create a `modules` folder in your maya user directory. For example, on Windows, that would mean creating `C:\Users\<your-username>\Documents\maya\modules`
3. Copy the `simplex.mod` file and the `simplex` folder into that directory.
4. Install numpy for mayapy [using pip](https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2022/ENU/Maya-Scripting/files/GUID-72A245EC-CDB4-46AB-BEE0-4BBBF9791627-htm.html). For example, on Windows, once you're in the right place the command will be `mayapy -m pip install numpy`. You will need admin privelages for this.
5. Run these two Python commands in Maya to start the tool. (This is probably what you should put into a shelf button)
```python
from simplexui import runSimplexUI
runSimplexUI()
```

## Uninstalling
1. Delete the `simplex.mod` file and the `simplex` folder from the `modules` folder in your maya user directory. For example, on Windows, that would mean deleting `C:\Users\<your-username>\Documents\maya\modules\simplex.mod` and `C:\Users\<your-username>\Documents\maya\modules\simplex`


## Compiling
Hopefully you don't need to do this, but if you have to, just take a look at `.github/workflows/main.yml` and you should be able to piece together how to get a compile working using CMake. You aren't required to download the devkit or set its path for CMake if you've got maya installed on your machine. Also note, I use features from CMake 3.16+ so I can target python 2 and 3 separately.
201 changes: 201 additions & 0 deletions simplex_maya_installer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import logging
import os
import sys
import zipfile
from pathlib import Path

from maya import cmds, mel

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


sys.dont_write_bytecode = True


def install_numpy(pyexe, target):
"""Install numpy to a particular folder
Arguments:
pyexe (str|Path): A path to the current python executable
target (str|Path): The folder to install to
Raises:
CalledProcessError: If the pip command fails
"""
import subprocess

cmd = [str(pyexe), "-m", "pip", "install", "--target", str(target), "numpy"]
proc = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)

if proc.returncode != 0:
logging.critical("\n\n")
logging.critical(proc.stdout)
logging.critical("\n\n")
cmds.confirmDialog(
title="Simplex Install Error",
message="Numpy install failed",
button=["OK"],
)
raise subprocess.CalledProcessError(proc.returncode, cmd, output=proc.stdout)


def get_latest_git_release(user, repo, asset_regex, out_path):
"""Get the latest github release from a particular user/repo and download
it to a specified path
Arguments:
user (str): The github user name to download from
repo (str): The github repo name to download
asset_regex (str): A regex to match against the name of the asset
out_path (str|Path): A filepath where the release should be downloaded to
Returns:
Path: The path that the file was downloaded to. This *technically* may be
different from the provided out_path
Raises:
ValueError: If the latest repo asset can't be found for download
"""
import json
import re
import urllib.request

latest_link = f"https://api.github.com/repos/{user}/{repo}/releases/latest"
f = urllib.request.urlopen(latest_link)
latest_release_data = json.loads(f.read())
assets = latest_release_data.get("assets", [])
download_url = None
for a in assets:
if re.match(asset_regex, a["name"]):
download_url = a["browser_download_url"]
break

if download_url is None:
asset_names = "\n".join([a["name"] for a in assets])
msg = f"regex: {asset_regex}\nnames:\n{asset_names}"
cmds.confirmDialog(
title="Simplex Install Error",
message="Release Download Failed",
button=["OK"],
)

raise ValueError(
f"Cannot find latest {user}/{repo} version to download.\nCheck your asset_regex\n{msg}"
)

out_path = Path(out_path)
outFolder = out_path.parent
outFolder.mkdir(exist_ok=True)
logger.info(f"Downloading latest simplex")
logger.info(f"from: {download_url}")
logger.info(f"to: {out_path}")
path, headers = urllib.request.urlretrieve(download_url, filename=out_path)
return Path(path)


def get_mayapy_path():
"""Get the path to the mayapy executable"""
binFolder = Path(sys.executable).parent
if sys.platform == "win32":
return binFolder / "mayapy.exe"
elif sys.platform == "darwin":
return binFolder / "mayapy"
elif sys.platform == "linux":
return binFolder / "mayapy"
cmds.confirmDialog(
title="Simplex Install Error",
message=f"Unsupported Platform: {sys.platform}",
button=["OK"],
)

raise RuntimeError(f"Current platform is unsupported: {sys.platform}")


def get_numpy_simplex_target(mod_folder):
"""Get the target path for the numpy simplex install"""

if sys.platform == "win32":
platform = "win64"
elif sys.platform == "darwin":
platform = "mac"
elif sys.platform == "linux":
platform = "linux"
else:
cmds.confirmDialog(
title="Simplex Install Error",
message=f"Unsupported Platform: {sys.platform}",
button=["OK"],
)
raise RuntimeError(f"Current platform is unsupported: {sys.platform}")

year = cmds.about(majorVersion=True)
nppath = mod_folder / "simplex" / f"{platform}-{year}" / "pyModules"
return nppath


def onMayaDroppedPythonFile(obj):
"""This function will get run when you drag/drop this python script onto maya"""
try:
# Ensure that people will report a full error
cmds.optionVar(intValue=("stackTraceIsOn", 1))
mel.eval('synchronizeScriptEditorOption(1, "StackTraceMenuItem")')

mod_folder = Path(cmds.internalVar(uad=True)) / "modules"
modfile = mod_folder / "simplex.mod"
simplex_zip = mod_folder / "simplex.zip"
moddir = mod_folder / "simplex"
if modfile.is_file() != moddir.is_dir():
msg = f"Simplex module is partially installed.\nPlease delete {modfile} and {moddir} and try again"
cmds.confirmDialog(
title="Simplex Install Error",
message=msg,
button=["OK"],
)
raise ValueError(msg)

if simplex_zip.is_file():
os.remove(simplex_zip)

# This will overwrite the existing install, but will leave any numpy installs alone
simplex_zip = get_latest_git_release(
"blurstudio",
"simplex",
r"simplex-v\d+\.\d+\.\d+\.zip",
simplex_zip,
)

if not simplex_zip.is_file():
cmds.confirmDialog(
title="Simplex Install Error",
message="Zip file download failed",
button=["OK"],
)
raise RuntimeError("Download of simplex zip failed")

with zipfile.ZipFile(simplex_zip, "r") as zip_ref:
zip_ref.extractall(mod_folder)
os.remove(simplex_zip)

try:
import numpy
except ModuleNotFoundError:
mayapy = get_mayapy_path()
target = get_numpy_simplex_target(mod_folder)
install_numpy(mayapy, target)
else:
logger.info("Numpy is already installed for this version of maya")
finally:
sys.dont_write_bytecode = False

cmds.confirmDialog(
title="Simplex Installed",
message="Simplex installation complete",
button=["OK"],
)

0 comments on commit 1c1687a

Please sign in to comment.