# MAYA MOCK COMPLETION

This project is a custom modification of Maya's *commands/api* stub libraries that allows you to execute python code that uses these libraries from a regular python interpreter, ideally the one from your venv.

Developing code for Maya can be a bit sluggish since it normally takes the following steps:

- Opening Maya (maybe multiple times).
- Setting up a way to send the code from your IDE to Maya.
- Setting up the command completion to get Maya's libraries on your IDE.
- Once code is sent, you need to refresh it to apply the changes unless you want to restart the app.

Also, if you are building your own packages you might have other dependencies that you might not want to install to your *mayapy* interpreter. Because of this you might have a separate virtual environment that contains these, but you cannot use a *mayapy* as a base interpreter for creating venvs.

What this package allows you is to separate your code from Maya to a certain degree. By installing this "mock" completion you can use Maya's libraries using a regular python interpreter.

This is different from using the application in *standalone* mode since you won't be initializing any maya at all.

> **Important:** The code will run since it will find Maya's modules (cmds, pymel, api...), and they won't throw any errors due to Maya not being open. However, **please notice that the objects generated by the api only return proxy objects and commands don't do anything real. They just "*pass*" or return other proxy objects with some information to manage them**.
> 

The utility from this is that you can play with these proxy objects and commands in a way that mimics Maya's behavior. Then, when you want you can execute that same code inside Maya and it should behave the same way but providing a meaningful output.

This can also be useful for quick UI development, making unittests and running them from your IDE of choice or making your code just more abstract overall by removing the necessity to run the code inside Maya.

## How to use

You can do one of the following:
- Install this package via pip once it is available on pypi and just import the modules on your code as normal.
- Save this package in your directory of choice and add the path to it to your interpreter's list of paths manually.

Then you should be able to run the code using the normal python interpreter.

```python
# Imports won't crash
import maya.cmds as mc
import maya.api.OpenMaya as om

mc.createNode('transform', name='mmc')  # Should provide flags suggestions with correct typing inference, but it won't do anything

sel_ls = om.MGlobal.getActiveSelectionList()  # Returns proxy MSelectionList

mobject = sel_ls.getDependNode(0)  # Get MObject from active selection

dep = om.MFnDependencyNode(mobject)  # Can initialize function sets

dep.name()  # >>> mmc
```

## Important! Node types and attribute caches

To determine if a node type exists or if an attribute exists on a node (alongisde their specs e.g. *is_array*, *is_element*, *attribute_types*), MMC uses some cache files.

Because of the sheer number of properties of nodes and attributes, a challenge this project faces is keeping the size of these files reasonable. However, that also means they might not cater your specific needs and so they might require updating based on your project's needs if one of these conditions apply:

1. *You are using custom nodes or nodes from plugins*. These have IDs and names that mmc cannot recognize from the get go.

2. *You are using a different maya version that contains node types not defined in the maps*.

3. You are using attributes from nodes that where not picked for the default mapping of attribute info.

### Attribute properties cache file

You will find the attributes cache file in `maya/attribute_properties.py`. To update it you will have to modify the `maya/generate_attrs_json.py` by adding the desired node types to query all of their attributes.

Then, you just simply have to define the desired output locations for the output cache files. Defaults:

```
{project_root}\maya\attribute_properties.py  # <-- contains attr info
{project_root}\maya\attribute_literals.py    # <-- for completions
```

### Node types cache

This one lives inside the `maya.api.OpenMaya` module (at the bottom of the file).
There is no current implementation to load these on runtime so I'd advise you to add your personal node MTypeIds from plugin nodes there.

Keep in mind that you will also have to add the matching string name and the type constant in MFnBase.

This implementation is still in process (no E.T.A, sorry).

# Disclaimers

- PySide2's completion hasn't been added in case you might want to run UI code using the real library. If this is not what you want you can use the same principle to run the code in the same way.

- This project is just a concept of a workflow. It might have its shortcomings, and it hasn't been tested in a real production, so I am not entirely sure how useful or reliable it actually is.

- This is still being updated as not all methods of the API mock completion return proxy objects. That is to say these will get updated as they are required.

Cheers and have fun!
