Pymxs, the 3DsMax bindings of Maxscript to Python doesn't come with any stubs

Overview

PyMXS Stubs generator

What

Pymxs, the 3DsMax bindings of Maxscript to Python doesn't come with any stubs. This is an attempt at generating stubs automatically by inspecting running code.

Generate stubs

Run generate_pymax_pyi.py in 3DsMax to generate stubs. Tested with 3DsMax 2021 (Python3).

Use stubs

Copy the pymxs.pyi file to a path where you'd usually be able to call import pymxs from.

These Stubs come as they are: I make no promises that they work or cover all your needs.

Development

  • Open Directory in VSCode
  • Pick the 3Ds Max Python as your interpreter
  • Unzip latest MXSPyCom Release into /mxspycom
  • Run debug/start_debug.py in Max
  • Run Debug configuration Python: Remote Attach
  • Run task Execute Script in 3Ds Max on generate_pymax_pyi.py file

Current scope

  • Works in 3Ds Max 2021
  • Works with Python 3
  • Gets properties of most 3DsMax objects

Missing from current version (to do)

  • Signatures for max script calls (need to go into __new__ constructors of the objects)
  • Some properties get skipped as the object they belong to can't be generated without the correct signature
  • No #Struct object types
  • No properties for regular object types (like Array)
  • Not all properties have the right hint (alot will still say None because they need initialization)
  • Some Max Scene clean up before, after, during script exectuion (this creates a TON of objects in your Max Scene)
  • Check other performance optimizations like turn off viewport rendering as applicable
  • Checking if everything is correct, including order of the pyi
  • Captialization rules - right now names are read as is, but might be worth enforcing some lowercase or CamelCase rules
  • Less hacky code
  • Streamline debug/development process
  • Encoding definition of pyi file
  • Callable for properties/arguments that need it

Contributing

Please feel free to fork and push Pull Requests my way. Also issues are welcome - in that case please include as much detail as possible.

Thanks

Autodesk License

3Ds Max, the maxscript API, pymxs and all other items belong to Autodesk.

Comments
  • Optimisation: Pre-compiling the pattern would be more performant.

    Optimisation: Pre-compiling the pattern would be more performant.

    https://github.com/friedererdmann/pymxs_stubs/blob/5f793a81fc621c5ed56dc6c4193cf8f4097bc921/parser.py#L61 Generally I like to pre-compile where possible to reduce overhead. Not a big thing here, but it can noticeably improve performance for lots of iterations.

    opened by ldunham1 2
  • Fix capitalization for class names

    Fix capitalization for class names

    Currently inheritance can break between classes as classes might be capitalized or not. This leads to classes inheriting from Color but the class color was not capitalized. By default all class names should be CamelCased, also to avoid clashes with built-ins (like set and Set).

    opened by friedererdmann 2
  • Clean up discarding invalid class and attribute names

    Clean up discarding invalid class and attribute names

    Currently checking for invalid class and attribute names happens in at least two different places and makes no use of any good logic. See if there's an easy regex or similar to sort out illegal names (starting with digit or special character) as well as discarding any attributes and class names that double with Python internal reserved words.

    opened by friedererdmann 1
  • Add structs

    Add structs

    I created a simple method to generate all the stubs for all StructDef objects. I've got a pretty vanilla install of Max 2023 so it should be free of third party plugins. Wasn't entirely sure how to properly integrate it into the rest of the stub generation, so I manually copy-pasted it into the .pyi file. Hopefully this is a good starting point!

    One thing to note was the <data> type for StructDef was, in all my testing, inaccessible and so I just assume it's private (even though it's listed as public). All <systemGlobal> types were accessible, so I assume they're public.

    opened by thomascswalker 0
  • Added support for certain struct types

    Added support for certain struct types

    Added functionality to parse some struct types for signatures. It doesn't cover all the types, but provides data on a large number of the outstanding ones. Currently formatted to return nested dictionaries with all the data like so:

    "SkinUtils": {
        "ExtractSkinData": {
            "signature": "<void>ExtractSkinData <node>node",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "ExtractSkinData "
                },
                {
                    "type": "node",
                    "name": "node"
                }
            ]
        },
        "ImportSkinData": {
            "signature": "<void>ImportSkinData <node>targetNode <node>sourceNode",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "ImportSkinData "
                },
                {
                    "type": "node",
                    "name": "targetNode "
                },
                {
                    "type": "node",
                    "name": "sourceNode"
                }
            ]
        },
        "GetBoneBindTM": {
            "signature": "<matrix3>GetBoneBindTM <node>skinNode <node>boneNode",
            "return_type": "matrix3",
            "arguments": [
                {
                    "type": "matrix3",
                    "name": "GetBoneBindTM "
                },
                {
                    "type": "node",
                    "name": "skinNode "
                },
                {
                    "type": "node",
                    "name": "boneNode"
                }
            ]
        },
        "SetBoneBindTM": {
            "signature": "<void>SetBoneBindTM <node>skinNode <node>boneNode <matrix3>tm",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "SetBoneBindTM "
                },
                {
                    "type": "node",
                    "name": "skinNode "
                },
                {
                    "type": "node",
                    "name": "boneNode "
                },
                {
                    "type": "matrix3",
                    "name": "tm"
                }
            ]
        },
        "GetMeshBindTM": {
            "signature": "<matrix3>GetMeshBindTM <node>skinNode",
            "return_type": "matrix3",
            "arguments": [
                {
                    "type": "matrix3",
                    "name": "GetMeshBindTM "
                },
                {
                    "type": "node",
                    "name": "skinNode"
                }
            ]
        },
        "SetMeshBindTM": {
            "signature": "<void>SetMeshBindTM <node>skinNode <matrix3>tm",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "SetMeshBindTM "
                },
                {
                    "type": "node",
                    "name": "skinNode "
                },
                {
                    "type": "matrix3",
                    "name": "tm"
                }
            ]
        },
        "GetBoneStretchTM": {
            "signature": "<matrix3>GetBoneStretchTM <node>skinNode <node>boneNode",
            "return_type": "matrix3",
            "arguments": [
                {
                    "type": "matrix3",
                    "name": "GetBoneStretchTM "
                },
                {
                    "type": "node",
                    "name": "skinNode "
                },
                {
                    "type": "node",
                    "name": "boneNode"
                }
            ]
        },
        "SetBoneStretchTM": {
            "signature": "<void>SetBoneStretchTM <node>skinNode <node>boneNode <matrix3>tm",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "SetBoneStretchTM "
                },
                {
                    "type": "node",
                    "name": "skinNode "
                },
                {
                    "type": "node",
                    "name": "boneNode "
                },
                {
                    "type": "matrix3",
                    "name": "tm"
                }
            ]
        },
        "GrowSelection": {
            "signature": "<void>GrowSelection <node>skinNode",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "GrowSelection "
                },
                {
                    "type": "node",
                    "name": "skinNode"
                }
            ]
        },
        "ShrinkSelection": {
            "signature": "<void>ShrinkSelection <node>skinNode",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "ShrinkSelection "
                },
                {
                    "type": "node",
                    "name": "skinNode"
                }
            ]
        },
        "LoopSelection": {
            "signature": "<void>LoopSelection <node>skinNode",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "LoopSelection "
                },
                {
                    "type": "node",
                    "name": "skinNode"
                }
            ]
        },
        "RingSelection": {
            "signature": "<void>RingSelection <node>skinNode",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "RingSelection "
                },
                {
                    "type": "node",
                    "name": "skinNode"
                }
            ]
        },
        "ImportSkinDataNoDialog": {
            "signature": "<void>ImportSkinDataNoDialog <boolean>matchByName <boolean>removeTargetPrefix <boolean>removeTargetSuffix <boolean>removeSourcePrefix <boolean>removeSourceSuffix <float>threshold <integer>interpolationType",
            "return_type": "void",
            "arguments": [
                {
                    "type": "void",
                    "name": "ImportSkinDataNoDialog "
                },
                {
                    "type": "boolean",
                    "name": "matchByName "
                },
                {
                    "type": "boolean",
                    "name": "removeTargetPrefix "
                },
                {
                    "type": "boolean",
                    "name": "removeTargetSuffix "
                },
                {
                    "type": "boolean",
                    "name": "removeSourcePrefix "
                },
                {
                    "type": "boolean",
                    "name": "removeSourceSuffix "
                },
                {
                    "type": "float",
                    "name": "threshold "
                },
                {
                    "type": "integer",
                    "name": "interpolationType"
                }
            ]
        }
    }
    
    opened by munkybutt 2
  • Streamline development process

    Streamline development process

    1. See if attaching debugger and starting pymxscom can be summarized in one launch profile.
    2. See if deploying pymxscom startup script can be automated
    3. See if linking VSCode workspace Python compiler to Max can be automated
    opened by friedererdmann 0
  • Make stub generation repeatable and less memory hungry

    Make stub generation repeatable and less memory hungry

    Optimize stub generation by cleaning the scene before and after the generation of the stubs. Investigate if turning off UI/Viewport elements can improve generation speed as well. Provide visual feedback how far along the stub generation is.

    opened by friedererdmann 1
  • Find and catalogue missing/broken properties

    Find and catalogue missing/broken properties

    A number of current properties default to None or its not possible to construct the base object without some signature, so they are ignored. Catalogue the missing or broken properties and create follow up tasks to fix them.

    opened by friedererdmann 0
Owner
Frieder Erdmann
Lead Technical Artist at Ubisoft Massive
Frieder Erdmann
Mypy stubs, i.e., type information, for numpy, pandas and matplotlib

Mypy type stubs for NumPy, pandas, and Matplotlib This is a PEP-561-compliant stub-only package which provides type information for matplotlib, numpy

Predictive Analytics Lab 194 Dec 19, 2022
PEP-484 typing stubs for SQLAlchemy 1.4 and SQLAlchemy 2.0

SQLAlchemy 2 Stubs These are PEP-484 typing stubs for SQLAlchemy 1.4 and 2.0. They are released concurrently along with a Mypy extension which is desi

SQLAlchemy 139 Dec 30, 2022
Tool for pinpointing circular imports in Python. Find cyclic imports in any project

Pycycle: Find and fix circular imports in python projects Pycycle is an experimental project that aims to help python developers fix their circular de

Vadim Kravcenko 311 Dec 15, 2022
Simple Python style checker in one Python file

pycodestyle (formerly called pep8) - Python style guide checker pycodestyle is a tool to check your Python code against some of the style conventions

Python Code Quality Authority 4.7k Jan 1, 2023
Optional static typing for Python 3 and 2 (PEP 484)

Mypy: Optional Static Typing for Python Got a question? Join us on Gitter! We don't have a mailing list; but we are always happy to answer questions o

Python 14.4k Jan 8, 2023
A Python Parser

parso - A Python Parser Parso is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python

Dave Halter 520 Dec 26, 2022
A simple program which checks Python source files for errors

Pyflakes A simple program which checks Python source files for errors. Pyflakes analyzes programs and detects various errors. It works by parsing the

Python Code Quality Authority 1.2k Dec 30, 2022
Performant type-checking for python.

Pyre is a performant type checker for Python compliant with PEP 484. Pyre can analyze codebases with millions of lines of code incrementally – providi

Facebook 6.2k Jan 4, 2023
A static type analyzer for Python code

pytype - ?? ✔ Pytype checks and infers types for your Python code - without requiring type annotations. Pytype can: Lint plain Python code, flagging c

Google 4k Dec 31, 2022
The strictest and most opinionated python linter ever!

wemake-python-styleguide Welcome to the strictest and most opinionated python linter ever. wemake-python-styleguide is actually a flake8 plugin with s

wemake.services 2.1k Jan 1, 2023
Static type checker for Python

Static type checker for Python Speed Pyright is a fast type checker meant for large Python source bases. It can run in a “watch” mode and performs fas

Microsoft 9.2k Jan 3, 2023
Tool to check the completeness of MANIFEST.in for Python packages

check-manifest Are you a Python developer? Have you uploaded packages to the Python Package Index? Have you accidentally uploaded broken packages with

Marius Gedminas 270 Dec 26, 2022
A python documentation linter which checks that the docstring description matches the definition.

Darglint A functional docstring linter which checks whether a docstring's description matches the actual function/method implementation. Darglint expe

Terrence Reilly 463 Dec 31, 2022
Flake8 plugin that checks import order against various Python Style Guides

flake8-import-order A flake8 and Pylama plugin that checks the ordering of your imports. It does not check anything else about the imports. Merely tha

Python Code Quality Authority 270 Nov 24, 2022
Flake8 extension for checking quotes in python

Flake8 Extension to lint for quotes. Major update in 2.0.0 We automatically encourage avoiding escaping quotes as per PEP 8. To disable this, use --no

Zachary Heller 157 Dec 13, 2022
Check for python builtins being used as variables or parameters

Flake8 Builtins plugin Check for python builtins being used as variables or parameters. Imagine some code like this: def max_values(list, list2):

Gil Forcada Codinachs 98 Jan 8, 2023
flake8 plugin to run black for checking Python coding style

flake8-black Introduction This is an MIT licensed flake8 plugin for validating Python code style with the command line code formatting tool black. It

Peter Cock 146 Dec 15, 2022
Custom Python linting through AST expressions

bellybutton bellybutton is a customizable, easy-to-configure linting engine for Python. What is this good for? Tools like pylint and flake8 provide, o

H. Chase Stevens 249 Dec 31, 2022
Unbearably fast O(1) runtime type-checking in pure Python.

Look for the bare necessities, the simple bare necessities. Forget about your worries and your strife. — The Jungle Book.

beartype 1.4k Jan 1, 2023