Updated
							
								
								
									
										0
									
								
								Scripts/Animation/epic_pose_wrangler/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,4 @@
 | 
			
		||||
# Sphinx build info version 1
 | 
			
		||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
 | 
			
		||||
config: 770bdf94db77f7f7445532076e8cf9ff
 | 
			
		||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
 | 
			
		||||
| 
		 After Width: | Height: | Size: 66 KiB  | 
| 
		 After Width: | Height: | Size: 45 KiB  | 
| 
		 After Width: | Height: | Size: 58 KiB  | 
@@ -0,0 +1,11 @@
 | 
			
		||||
API
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
pose\_wrangler.v2.main
 | 
			
		||||
+++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
.. autoclass:: pose_wrangler.v2.main.UERBFAPI
 | 
			
		||||
   :members:
 | 
			
		||||
   :undoc-members:
 | 
			
		||||
   :show-inheritance:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
Extensions
 | 
			
		||||
=========================================
 | 
			
		||||
 | 
			
		||||
You can now create custom extensions for PoseWrangler so you can introduce new features without having to edit the
 | 
			
		||||
core code base.
 | 
			
		||||
 | 
			
		||||
Custom extensions can be created by inheriting from the following class:
 | 
			
		||||
 | 
			
		||||
.. autoclass:: pose_wrangler.v2.model.base_extension.PoseWranglerExtension
 | 
			
		||||
   :members:
 | 
			
		||||
   :undoc-members:
 | 
			
		||||
   :show-inheritance:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
When PoseWrangler loads up, it will automatically detect and load any classes that inherit from ``PoseWranglerExtension``
 | 
			
		||||
on startup.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    To make sure that your extension loads, please make sure that it is imported before you start PoseWrangler.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Example extensions can be found under ``pose_wrangler.v2.extensions``
 | 
			
		||||
@@ -0,0 +1,61 @@
 | 
			
		||||
.. Pose Wrangler documentation master file, created by
 | 
			
		||||
   sphinx-quickstart on Thu May 12 15:11:40 2022.
 | 
			
		||||
   You can adapt this file completely to your liking, but it should at least
 | 
			
		||||
   contain the root `toctree` directive.
 | 
			
		||||
 | 
			
		||||
Pose Wrangler Documentation
 | 
			
		||||
=========================================
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :maxdepth: 2
 | 
			
		||||
   :caption: Contents:
 | 
			
		||||
 | 
			
		||||
   overview
 | 
			
		||||
   upgrading
 | 
			
		||||
   mirror_mapping
 | 
			
		||||
   extensions
 | 
			
		||||
   api
 | 
			
		||||
 | 
			
		||||
Overview
 | 
			
		||||
===================================
 | 
			
		||||
PoseWrangler is a tool for interfacing with Epic's MayaUERBFPlugin. The plugin is distributed by Epic Games and installed via Quixel Bridge.
 | 
			
		||||
 | 
			
		||||
Versions
 | 
			
		||||
-------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
1.0.0:
 | 
			
		||||
+++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
- Supports legacy scenes created with the UE4RBFSolverNode
 | 
			
		||||
- Supports Maya 2018-2022
 | 
			
		||||
- Provides upgrade workflow to migrate to V2
 | 
			
		||||
 | 
			
		||||
2.0.0:
 | 
			
		||||
+++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
- Supports scenes created with the UERBFSolverNode
 | 
			
		||||
- Multiple Driver Support
 | 
			
		||||
- Initial blendshape support (WIP)
 | 
			
		||||
- Supports Maya 2018-2022
 | 
			
		||||
- Support for custom mirror mappings to allow for rigs with naming conventions that deviate from the default UE5 conventions
 | 
			
		||||
- Fully automatable via Python and MayaPy
 | 
			
		||||
- Serialization/deserialization to dictionary or JSON file
 | 
			
		||||
- Support for custom extensions and context menu actions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contributors
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
- Chris Evans
 | 
			
		||||
- Judd Simantov
 | 
			
		||||
- David Corral
 | 
			
		||||
- Borna Berc
 | 
			
		||||
- Chris Theodosius
 | 
			
		||||
 | 
			
		||||
Indices and tables
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
* :ref:`genindex`
 | 
			
		||||
* :ref:`modindex`
 | 
			
		||||
* :ref:`search`
 | 
			
		||||
@@ -0,0 +1,59 @@
 | 
			
		||||
Mirror Mapping
 | 
			
		||||
=========================================
 | 
			
		||||
 | 
			
		||||
Mirror mapping enables Pose Wrangler to support custom skeletons when mirroring RBF solvers and poses.
 | 
			
		||||
 | 
			
		||||
Below is the mirror mapping for characters following the MetaHuman naming conventions:
 | 
			
		||||
 | 
			
		||||
  .. code-block:: JSON
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "solver_expression": "(?P<prefix>[a-zA-Z0-9]+)?(?P<side>_[lr]{1}_)(?P<suffix>[a-zA-Z0-9_]+)",
 | 
			
		||||
        "transform_expression": "(?P<prefix>[a-zA-Z0-9_]+)?(?P<side>_[lr]{1}_)(?P<suffix>[a-zA-Z0-9_]+)",
 | 
			
		||||
        "left": {
 | 
			
		||||
            "solver_syntax": "_l_",
 | 
			
		||||
            "transform_syntax": "_l_"
 | 
			
		||||
            },
 | 
			
		||||
        "right": {
 | 
			
		||||
            "solver_syntax": "_r_",
 | 
			
		||||
            "transform_syntax": "_r_"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
.. list-table:: Title
 | 
			
		||||
   :widths: 25 50
 | 
			
		||||
   :header-rows: 1
 | 
			
		||||
 | 
			
		||||
   * - Key
 | 
			
		||||
     - Definition
 | 
			
		||||
   * - solver_expression
 | 
			
		||||
     - A regular expression used to match against the solver node name
 | 
			
		||||
   * - transform_expression
 | 
			
		||||
     - A regular expression used to match against the transform (joint) node name
 | 
			
		||||
   * - left
 | 
			
		||||
     - dictionary containing the expected match for the solver_expression and |br| transform_expression
 | 
			
		||||
   * - right
 | 
			
		||||
     - dictionary containing the expected match for the solver_expression and |br| transform_expression
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    As an example if we wanted to mirror a solver called ``calf_l_UERBFSolver`` we first try to match the name
 | 
			
		||||
    of the solver against the ``solver_expression``. If the match fails, you'll see an error appear in the output
 | 
			
		||||
    log that the solver name doesn't match the settings defined in mirror mapping.
 | 
			
		||||
 | 
			
		||||
    If the match succeeds, it will then iterate through the groups in the matchdict to determine if one of the groups
 | 
			
		||||
    matches the ``solver_syntax`` for the left hand side. If it does, it will replace it with the right and vice versa.
 | 
			
		||||
 | 
			
		||||
    In this case, we will end up with a matchdict that looks something like this: |br|
 | 
			
		||||
    ``{"prefix": "calf", "side": "_l_", "suffix": "UERBFSolver"}`` |br|
 | 
			
		||||
    The mapping will iterate through this dictionary and attempt to match each value against the ``solver_syntax`` of
 | 
			
		||||
    the ``left`` and ``right`` group defined in mirror mapping. If it matches the ``left`` group it will replace the
 | 
			
		||||
    ``side`` value with the ``solver_syntax`` specified in the ``right`` group resulting in the following dictionary: |br|
 | 
			
		||||
    ``{"prefix": "calf", "side": "_r_", "suffix": "UERBFSolver"}`` |br|
 | 
			
		||||
 | 
			
		||||
    The same thing then happens for the drivers and driven transforms associated with the solver, using ``transform_expression``
 | 
			
		||||
    and ``transform_syntax`` in place of the solver.
 | 
			
		||||
 | 
			
		||||
.. |br| raw:: html
 | 
			
		||||
 | 
			
		||||
     <br>
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
2.0.0 Overview
 | 
			
		||||
=========================================
 | 
			
		||||
 | 
			
		||||
Version 2.0.0 is a refactor of the original Pose Wrangler. The goal of this version has been to separate the UI
 | 
			
		||||
logic from the backend, enabling users to automate RBF setup via Python and create custom extensions to add new
 | 
			
		||||
functionality.
 | 
			
		||||
 | 
			
		||||
UI Overview
 | 
			
		||||
-------------------------------
 | 
			
		||||
 | 
			
		||||
.. image:: /images/overview.png
 | 
			
		||||
    :width: 800
 | 
			
		||||
    :alt: UI Overview
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
1) Solver View
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Here is where you can find a list of all the RBF solvers currently available in the scene and can edit, create, delete
 | 
			
		||||
or mirror solvers.
 | 
			
		||||
 | 
			
		||||
In order to make changes to the poses, drivers or driven transforms/blendshapes you need to toggle a solver into `edit`
 | 
			
		||||
mode via the `Edit Selected Solver` button.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    Only one solver can be edited at a single time.
 | 
			
		||||
 | 
			
		||||
2) Pose View
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Here you can find a list of all the poses. In order to make any changes to the poses, you need to edit the corresponding solver.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
    Most of these are self-explanatory, but is it worth noting that `Mute Pose` will enable and disable the pose on the
 | 
			
		||||
    solver via the `targetEnable` attribute. This means that if the RBF solver node is set to use `automatic radius`
 | 
			
		||||
    then the radius will be calculated without the influence of the muted poses.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
3) Driver View
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
2.0.0 supports multiple drivers. Here you can add/remove driver transforms.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
4) Driven Transforms / Blendshape View
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
Here you can add/remove driven transforms and create/add blendshapes.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    The blendshape workflow is currently a work in progress and may change in the future.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
5) Extensions and Settings View
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
Pose Wrangler now supports writing custom extensions for the tool that can be embedded into the UI here.
 | 
			
		||||
`Core Extensions` are default extensions that ship with Pose Wrangler. `Pose Exporter` is an example of a custom
 | 
			
		||||
extension used by the MetaHuman team. For more information on how these extensions work and how to create your own,
 | 
			
		||||
please refer to the :doc:`extensions` page.
 | 
			
		||||
 | 
			
		||||
You can also change the mirror mapping, which will allow you to specify a custom mapping if your skeleton does not
 | 
			
		||||
match the default MetaHuman skeleton and the mirror solver/pose functionality is causing unexpected results.
 | 
			
		||||
 | 
			
		||||
6) Top Menu
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
Here you can import/export RBF solvers to/from a JSON file, change the theme and view the help.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
7) Output Log
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 | 
			
		||||
Displays debug, info, warning and error messages.
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
Upgrading to 2.0.0
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
When you load up Pose Wrangler with a scene that contains `UE4RBFSolverNode` you will be greeted with the new legacy
 | 
			
		||||
version of PoseWrangler. This version is almost identical with the version previously available via GitHub, with the
 | 
			
		||||
addition of the log window and the upgrade button.
 | 
			
		||||
 | 
			
		||||
If you have the new version of the plugin available you will be presented with an option to upgrade your scene at the
 | 
			
		||||
top of the Pose Wrangler window. Pressing this button will execute an upgrade script that will replace all the
 | 
			
		||||
`UE4RBFSolverNode` with `UERBFSolverNode` and clean up old/redundant nodes left lingering in the scene.
 | 
			
		||||
 | 
			
		||||
.. image:: /images/upgrade.png
 | 
			
		||||
    :width: 800
 | 
			
		||||
    :alt: UI Overview
 | 
			
		||||
 | 
			
		||||
If the upgrade is successful you will be presented with the new tool window.
 | 
			
		||||
 | 
			
		||||
.. image:: /images/v2.png
 | 
			
		||||
    :width: 800
 | 
			
		||||
    :alt: UI Overview
 | 
			
		||||
@@ -0,0 +1,906 @@
 | 
			
		||||
/*
 | 
			
		||||
 * basic.css
 | 
			
		||||
 * ~~~~~~~~~
 | 
			
		||||
 *
 | 
			
		||||
 * Sphinx stylesheet -- basic theme.
 | 
			
		||||
 *
 | 
			
		||||
 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
 | 
			
		||||
 * :license: BSD, see LICENSE for details.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* -- main layout ----------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.clearer {
 | 
			
		||||
    clear: both;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.section::after {
 | 
			
		||||
    display: block;
 | 
			
		||||
    content: '';
 | 
			
		||||
    clear: left;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- relbar ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.related {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    font-size: 90%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.related h3 {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.related ul {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 0 0 0 10px;
 | 
			
		||||
    list-style: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.related li {
 | 
			
		||||
    display: inline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.related li.right {
 | 
			
		||||
    float: right;
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- sidebar --------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebarwrapper {
 | 
			
		||||
    padding: 10px 5px 0 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 230px;
 | 
			
		||||
    margin-left: -100%;
 | 
			
		||||
    font-size: 90%;
 | 
			
		||||
    word-wrap: break-word;
 | 
			
		||||
    overflow-wrap : break-word;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar ul {
 | 
			
		||||
    list-style: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar ul ul,
 | 
			
		||||
div.sphinxsidebar ul.want-points {
 | 
			
		||||
    margin-left: 20px;
 | 
			
		||||
    list-style: square;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar ul ul {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar form {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar input {
 | 
			
		||||
    border: 1px solid #98dbcc;
 | 
			
		||||
    font-family: sans-serif;
 | 
			
		||||
    font-size: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar #searchbox form.search {
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar #searchbox input[type="text"] {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 80%;
 | 
			
		||||
    padding: 0.25em;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sphinxsidebar #searchbox input[type="submit"] {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 20%;
 | 
			
		||||
    border-left: none;
 | 
			
		||||
    padding: 0.25em;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
img {
 | 
			
		||||
    border: 0;
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- search page ----------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
ul.search {
 | 
			
		||||
    margin: 10px 0 0 20px;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ul.search li {
 | 
			
		||||
    padding: 5px 0 5px 20px;
 | 
			
		||||
    background-image: url(file.png);
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    background-position: 0 7px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ul.search li a {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ul.search li p.context {
 | 
			
		||||
    color: #888;
 | 
			
		||||
    margin: 2px 0 0 30px;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ul.keywordmatches li.goodmatch a {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- index page ------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
table.contentstable {
 | 
			
		||||
    width: 90%;
 | 
			
		||||
    margin-left: auto;
 | 
			
		||||
    margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.contentstable p.biglink {
 | 
			
		||||
    line-height: 150%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.biglink {
 | 
			
		||||
    font-size: 1.3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
span.linkdescr {
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
    padding-top: 5px;
 | 
			
		||||
    font-size: 90%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- general index --------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
table.indextable {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.indextable td {
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.indextable ul {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
    list-style-type: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.indextable > tbody > tr > td > ul {
 | 
			
		||||
    padding-left: 0em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.indextable tr.pcap {
 | 
			
		||||
    height: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.indextable tr.cap {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
    background-color: #f2f2f2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.toggler {
 | 
			
		||||
    margin-right: 3px;
 | 
			
		||||
    margin-top: 3px;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.modindex-jumpbox {
 | 
			
		||||
    border-top: 1px solid #ddd;
 | 
			
		||||
    border-bottom: 1px solid #ddd;
 | 
			
		||||
    margin: 1em 0 1em 0;
 | 
			
		||||
    padding: 0.4em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.genindex-jumpbox {
 | 
			
		||||
    border-top: 1px solid #ddd;
 | 
			
		||||
    border-bottom: 1px solid #ddd;
 | 
			
		||||
    margin: 1em 0 1em 0;
 | 
			
		||||
    padding: 0.4em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- domain module index --------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
table.modindextable td {
 | 
			
		||||
    padding: 2px;
 | 
			
		||||
    border-collapse: collapse;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- general body styles --------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.body {
 | 
			
		||||
    min-width: 450px;
 | 
			
		||||
    max-width: 800px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.body p, div.body dd, div.body li, div.body blockquote {
 | 
			
		||||
    -moz-hyphens: auto;
 | 
			
		||||
    -ms-hyphens: auto;
 | 
			
		||||
    -webkit-hyphens: auto;
 | 
			
		||||
    hyphens: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.headerlink {
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.brackets:before,
 | 
			
		||||
span.brackets > a:before{
 | 
			
		||||
    content: "[";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.brackets:after,
 | 
			
		||||
span.brackets > a:after {
 | 
			
		||||
    content: "]";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1:hover > a.headerlink,
 | 
			
		||||
h2:hover > a.headerlink,
 | 
			
		||||
h3:hover > a.headerlink,
 | 
			
		||||
h4:hover > a.headerlink,
 | 
			
		||||
h5:hover > a.headerlink,
 | 
			
		||||
h6:hover > a.headerlink,
 | 
			
		||||
dt:hover > a.headerlink,
 | 
			
		||||
caption:hover > a.headerlink,
 | 
			
		||||
p.caption:hover > a.headerlink,
 | 
			
		||||
div.code-block-caption:hover > a.headerlink {
 | 
			
		||||
    visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.body p.caption {
 | 
			
		||||
    text-align: inherit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.body td {
 | 
			
		||||
    text-align: left;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.first {
 | 
			
		||||
    margin-top: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p.rubric {
 | 
			
		||||
    margin-top: 30px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.align-left, figure.align-left, .figure.align-left, object.align-left {
 | 
			
		||||
    clear: left;
 | 
			
		||||
    float: left;
 | 
			
		||||
    margin-right: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.align-right, figure.align-right, .figure.align-right, object.align-right {
 | 
			
		||||
    clear: right;
 | 
			
		||||
    float: right;
 | 
			
		||||
    margin-left: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.align-center, figure.align-center, .figure.align-center, object.align-center {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
  margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.align-default, figure.align-default, .figure.align-default {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
  margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.align-left {
 | 
			
		||||
    text-align: left;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.align-center {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.align-default {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.align-right {
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- sidebars -------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.sidebar,
 | 
			
		||||
aside.sidebar {
 | 
			
		||||
    margin: 0 0 0.5em 1em;
 | 
			
		||||
    border: 1px solid #ddb;
 | 
			
		||||
    padding: 7px;
 | 
			
		||||
    background-color: #ffe;
 | 
			
		||||
    width: 40%;
 | 
			
		||||
    float: right;
 | 
			
		||||
    clear: right;
 | 
			
		||||
    overflow-x: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p.sidebar-title {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.admonition, div.topic, blockquote {
 | 
			
		||||
    clear: left;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- topics ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.topic {
 | 
			
		||||
    border: 1px solid #ccc;
 | 
			
		||||
    padding: 7px;
 | 
			
		||||
    margin: 10px 0 10px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p.topic-title {
 | 
			
		||||
    font-size: 1.1em;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- admonitions ----------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.admonition {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
    padding: 7px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.admonition dt {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p.admonition-title {
 | 
			
		||||
    margin: 0px 10px 5px 0px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.body p.centered {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    margin-top: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- content of sidebars/topics/admonitions -------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.sidebar > :last-child,
 | 
			
		||||
aside.sidebar > :last-child,
 | 
			
		||||
div.topic > :last-child,
 | 
			
		||||
div.admonition > :last-child {
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.sidebar::after,
 | 
			
		||||
aside.sidebar::after,
 | 
			
		||||
div.topic::after,
 | 
			
		||||
div.admonition::after,
 | 
			
		||||
blockquote::after {
 | 
			
		||||
    display: block;
 | 
			
		||||
    content: '';
 | 
			
		||||
    clear: both;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- tables ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
table.docutils {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    border-collapse: collapse;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.align-center {
 | 
			
		||||
    margin-left: auto;
 | 
			
		||||
    margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.align-default {
 | 
			
		||||
    margin-left: auto;
 | 
			
		||||
    margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table caption span.caption-number {
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table caption span.caption-text {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.docutils td, table.docutils th {
 | 
			
		||||
    padding: 1px 8px 1px 5px;
 | 
			
		||||
    border-top: 0;
 | 
			
		||||
    border-left: 0;
 | 
			
		||||
    border-right: 0;
 | 
			
		||||
    border-bottom: 1px solid #aaa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.footnote td, table.footnote th {
 | 
			
		||||
    border: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
th {
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    padding-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.citation {
 | 
			
		||||
    border-left: solid 1px gray;
 | 
			
		||||
    margin-left: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.citation td {
 | 
			
		||||
    border-bottom: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
th > :first-child,
 | 
			
		||||
td > :first-child {
 | 
			
		||||
    margin-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
th > :last-child,
 | 
			
		||||
td > :last-child {
 | 
			
		||||
    margin-bottom: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- figures --------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
div.figure, figure {
 | 
			
		||||
    margin: 0.5em;
 | 
			
		||||
    padding: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.figure p.caption, figcaption {
 | 
			
		||||
    padding: 0.3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.figure p.caption span.caption-number,
 | 
			
		||||
figcaption span.caption-number {
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.figure p.caption span.caption-text,
 | 
			
		||||
figcaption span.caption-text {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- field list styles ----------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
table.field-list td, table.field-list th {
 | 
			
		||||
    border: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.field-list ul {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding-left: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.field-list p {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.field-name {
 | 
			
		||||
    -moz-hyphens: manual;
 | 
			
		||||
    -ms-hyphens: manual;
 | 
			
		||||
    -webkit-hyphens: manual;
 | 
			
		||||
    hyphens: manual;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- hlist styles ---------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
table.hlist {
 | 
			
		||||
    margin: 1em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.hlist td {
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- object description styles --------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.sig {
 | 
			
		||||
	font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig-name, code.descname {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig-name {
 | 
			
		||||
	font-size: 1.1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code.descname {
 | 
			
		||||
    font-size: 1.2em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig-prename, code.descclassname {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.optional {
 | 
			
		||||
    font-size: 1.3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig-paren {
 | 
			
		||||
    font-size: larger;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig-param.n {
 | 
			
		||||
	font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* C++ specific styling */
 | 
			
		||||
 | 
			
		||||
.sig-inline.c-texpr,
 | 
			
		||||
.sig-inline.cpp-texpr {
 | 
			
		||||
	font-family: unset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig.c   .k, .sig.c   .kt,
 | 
			
		||||
.sig.cpp .k, .sig.cpp .kt {
 | 
			
		||||
	color: #0033B3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig.c   .m,
 | 
			
		||||
.sig.cpp .m {
 | 
			
		||||
	color: #1750EB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sig.c   .s, .sig.c   .sc,
 | 
			
		||||
.sig.cpp .s, .sig.cpp .sc {
 | 
			
		||||
	color: #067D17;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -- other body styles ----------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
ol.arabic {
 | 
			
		||||
    list-style: decimal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.loweralpha {
 | 
			
		||||
    list-style: lower-alpha;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.upperalpha {
 | 
			
		||||
    list-style: upper-alpha;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.lowerroman {
 | 
			
		||||
    list-style: lower-roman;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.upperroman {
 | 
			
		||||
    list-style: upper-roman;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:not(li) > ol > li:first-child > :first-child,
 | 
			
		||||
:not(li) > ul > li:first-child > :first-child {
 | 
			
		||||
    margin-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:not(li) > ol > li:last-child > :last-child,
 | 
			
		||||
:not(li) > ul > li:last-child > :last-child {
 | 
			
		||||
    margin-bottom: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.simple ol p,
 | 
			
		||||
ol.simple ul p,
 | 
			
		||||
ul.simple ol p,
 | 
			
		||||
ul.simple ul p {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.simple > li:not(:first-child) > p,
 | 
			
		||||
ul.simple > li:not(:first-child) > p {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.simple p,
 | 
			
		||||
ul.simple p {
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.footnote > dt,
 | 
			
		||||
dl.citation > dt {
 | 
			
		||||
    float: left;
 | 
			
		||||
    margin-right: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.footnote > dd,
 | 
			
		||||
dl.citation > dd {
 | 
			
		||||
    margin-bottom: 0em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.footnote > dd:after,
 | 
			
		||||
dl.citation > dd:after {
 | 
			
		||||
    content: "";
 | 
			
		||||
    clear: both;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.field-list {
 | 
			
		||||
    display: grid;
 | 
			
		||||
    grid-template-columns: fit-content(30%) auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.field-list > dt {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    word-break: break-word;
 | 
			
		||||
    padding-left: 0.5em;
 | 
			
		||||
    padding-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.field-list > dt:after {
 | 
			
		||||
    content: ":";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.field-list > dd {
 | 
			
		||||
    padding-left: 0.5em;
 | 
			
		||||
    margin-top: 0em;
 | 
			
		||||
    margin-left: 0em;
 | 
			
		||||
    margin-bottom: 0em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl {
 | 
			
		||||
    margin-bottom: 15px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dd > :first-child {
 | 
			
		||||
    margin-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dd ul, dd table {
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dd {
 | 
			
		||||
    margin-top: 3px;
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
    margin-left: 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl > dd:last-child,
 | 
			
		||||
dl > dd:last-child > :last-child {
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dt:target, span.highlighted {
 | 
			
		||||
    background-color: #fbe54e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rect.highlighted {
 | 
			
		||||
    fill: #fbe54e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.glossary dt {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    font-size: 1.1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.versionmodified {
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.system-message {
 | 
			
		||||
    background-color: #fda;
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
    border: 3px solid red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.footnote:target  {
 | 
			
		||||
    background-color: #ffa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.line-block {
 | 
			
		||||
    display: block;
 | 
			
		||||
    margin-top: 1em;
 | 
			
		||||
    margin-bottom: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.line-block .line-block {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
    margin-bottom: 0;
 | 
			
		||||
    margin-left: 1.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.guilabel, .menuselection {
 | 
			
		||||
    font-family: sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.accelerator {
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.classifier {
 | 
			
		||||
    font-style: oblique;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.classifier:before {
 | 
			
		||||
    font-style: normal;
 | 
			
		||||
    margin: 0 0.5em;
 | 
			
		||||
    content: ":";
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abbr, acronym {
 | 
			
		||||
    border-bottom: dotted 1px;
 | 
			
		||||
    cursor: help;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- code displays --------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
pre {
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pre, div[class*="highlight-"] {
 | 
			
		||||
    clear: both;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
span.pre {
 | 
			
		||||
    -moz-hyphens: none;
 | 
			
		||||
    -ms-hyphens: none;
 | 
			
		||||
    -webkit-hyphens: none;
 | 
			
		||||
    hyphens: none;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div[class*="highlight-"] {
 | 
			
		||||
    margin: 1em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
td.linenos pre {
 | 
			
		||||
    border: 0;
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    color: #aaa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable {
 | 
			
		||||
    display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable tbody {
 | 
			
		||||
    display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable tr {
 | 
			
		||||
    display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable td {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable td.linenos {
 | 
			
		||||
    padding-right: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable td.code {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.highlight .hll {
 | 
			
		||||
    display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.highlight pre,
 | 
			
		||||
table.highlighttable pre {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.code-block-caption + div {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.code-block-caption {
 | 
			
		||||
    margin-top: 1em;
 | 
			
		||||
    padding: 2px 5px;
 | 
			
		||||
    font-size: small;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.code-block-caption code {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.highlighttable td.linenos,
 | 
			
		||||
span.linenos,
 | 
			
		||||
div.highlight span.gp {  /* gp: Generic.Prompt */
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  -webkit-user-select: text; /* Safari fallback only */
 | 
			
		||||
  -webkit-user-select: none; /* Chrome/Safari */
 | 
			
		||||
  -moz-user-select: none; /* Firefox */
 | 
			
		||||
  -ms-user-select: none; /* IE10+ */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.code-block-caption span.caption-number {
 | 
			
		||||
    padding: 0.1em 0.3em;
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.code-block-caption span.caption-text {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.literal-block-wrapper {
 | 
			
		||||
    margin: 1em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code.xref, a code {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.viewcode-link {
 | 
			
		||||
    float: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.viewcode-back {
 | 
			
		||||
    float: right;
 | 
			
		||||
    font-family: sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.viewcode-block:target {
 | 
			
		||||
    margin: -1px -10px;
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- math display ---------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
img.math {
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.body div.math p {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
span.eqno {
 | 
			
		||||
    float: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
span.eqno a.headerlink {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    z-index: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.math:hover a.headerlink {
 | 
			
		||||
    visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- printout stylesheet --------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
@media print({
 | 
			
		||||
    div.document,
 | 
			
		||||
    div.documentwrapper,
 | 
			
		||||
    div.bodywrapper {
 | 
			
		||||
        margin: 0 !important;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    div.sphinxsidebar,
 | 
			
		||||
    div.related,
 | 
			
		||||
    div.footer,
 | 
			
		||||
    #top-link {
 | 
			
		||||
        display: none;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
 | 
			
		||||
| 
		 After Width: | Height: | Size: 434 KiB  | 
@@ -0,0 +1,358 @@
 | 
			
		||||
/*
 | 
			
		||||
 * doctools.js
 | 
			
		||||
 * ~~~~~~~~~~~
 | 
			
		||||
 *
 | 
			
		||||
 * Sphinx JavaScript utilities for all documentation.
 | 
			
		||||
 *
 | 
			
		||||
 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
 | 
			
		||||
 * :license: BSD, see LICENSE for details.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * select a different prefix for underscore
 | 
			
		||||
 */
 | 
			
		||||
$u = _.noConflict();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * make the code below compatible with browsers without
 | 
			
		||||
 * an installed firebug like debugger
 | 
			
		||||
if (!window.console || !console.firebug) {
 | 
			
		||||
  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
 | 
			
		||||
    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
 | 
			
		||||
    "profile", "profileEnd"];
 | 
			
		||||
  window.console = {};
 | 
			
		||||
  for (var i = 0; i < names.length; ++i)
 | 
			
		||||
    window.console[names[i]] = function() {};
 | 
			
		||||
}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * small helper function to urldecode strings
 | 
			
		||||
 *
 | 
			
		||||
 * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
 | 
			
		||||
 */
 | 
			
		||||
jQuery.urldecode = function(x) {
 | 
			
		||||
  if (!x) {
 | 
			
		||||
    return x
 | 
			
		||||
  }
 | 
			
		||||
  return decodeURIComponent(x.replace(/\+/g, ' '));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * small helper function to urlencode strings
 | 
			
		||||
 */
 | 
			
		||||
jQuery.urlencode = encodeURIComponent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This function returns the parsed url parameters of the
 | 
			
		||||
 * current request. Multiple values per key are supported,
 | 
			
		||||
 * it will always return arrays of strings for the value parts.
 | 
			
		||||
 */
 | 
			
		||||
jQuery.getQueryParameters = function(s) {
 | 
			
		||||
  if (typeof s === 'undefined')
 | 
			
		||||
    s = document.location.search;
 | 
			
		||||
  var parts = s.substr(s.indexOf('?') + 1).split('&');
 | 
			
		||||
  var result = {};
 | 
			
		||||
  for (var i = 0; i < parts.length; i++) {
 | 
			
		||||
    var tmp = parts[i].split('=', 2);
 | 
			
		||||
    var key = jQuery.urldecode(tmp[0]);
 | 
			
		||||
    var value = jQuery.urldecode(tmp[1]);
 | 
			
		||||
    if (key in result)
 | 
			
		||||
      result[key].push(value);
 | 
			
		||||
    else
 | 
			
		||||
      result[key] = [value];
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * highlight a given string on a jquery object by wrapping it in
 | 
			
		||||
 * span elements with the given class name.
 | 
			
		||||
 */
 | 
			
		||||
jQuery.fn.highlightText = function(text, className) {
 | 
			
		||||
  function highlight(node, addItems) {
 | 
			
		||||
    if (node.nodeType === 3) {
 | 
			
		||||
      var val = node.nodeValue;
 | 
			
		||||
      var pos = val.toLowerCase().indexOf(text);
 | 
			
		||||
      if (pos >= 0 &&
 | 
			
		||||
          !jQuery(node.parentNode).hasClass(className) &&
 | 
			
		||||
          !jQuery(node.parentNode).hasClass("nohighlight")) {
 | 
			
		||||
        var span;
 | 
			
		||||
        var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
 | 
			
		||||
        if (isInSVG) {
 | 
			
		||||
          span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
 | 
			
		||||
        } else {
 | 
			
		||||
          span = document.createElement("span");
 | 
			
		||||
          span.className = className;
 | 
			
		||||
        }
 | 
			
		||||
        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
 | 
			
		||||
        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
 | 
			
		||||
          document.createTextNode(val.substr(pos + text.length)),
 | 
			
		||||
          node.nextSibling));
 | 
			
		||||
        node.nodeValue = val.substr(0, pos);
 | 
			
		||||
        if (isInSVG) {
 | 
			
		||||
          var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
 | 
			
		||||
          var bbox = node.parentElement.getBBox();
 | 
			
		||||
          rect.x.baseVal.value = bbox.x;
 | 
			
		||||
          rect.y.baseVal.value = bbox.y;
 | 
			
		||||
          rect.width.baseVal.value = bbox.width;
 | 
			
		||||
          rect.height.baseVal.value = bbox.height;
 | 
			
		||||
          rect.setAttribute('class', className);
 | 
			
		||||
          addItems.push({
 | 
			
		||||
              "parent": node.parentNode,
 | 
			
		||||
              "target": rect});
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else if (!jQuery(node).is("button, select, textarea")) {
 | 
			
		||||
      jQuery.each(node.childNodes, function() {
 | 
			
		||||
        highlight(this, addItems);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  var addItems = [];
 | 
			
		||||
  var result = this.each(function() {
 | 
			
		||||
    highlight(this, addItems);
 | 
			
		||||
  });
 | 
			
		||||
  for (var i = 0; i < addItems.length; ++i) {
 | 
			
		||||
    jQuery(addItems[i].parent).before(addItems[i].target);
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * backward compatibility for jQuery.browser
 | 
			
		||||
 * This will be supported until firefox bug is fixed.
 | 
			
		||||
 */
 | 
			
		||||
if (!jQuery.browser) {
 | 
			
		||||
  jQuery.uaMatch = function(ua) {
 | 
			
		||||
    ua = ua.toLowerCase();
 | 
			
		||||
 | 
			
		||||
    var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
 | 
			
		||||
      /(webkit)[ \/]([\w.]+)/.exec(ua) ||
 | 
			
		||||
      /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
 | 
			
		||||
      /(msie) ([\w.]+)/.exec(ua) ||
 | 
			
		||||
      ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
 | 
			
		||||
      [];
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      browser: match[ 1 ] || "",
 | 
			
		||||
      version: match[ 2 ] || "0"
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  jQuery.browser = {};
 | 
			
		||||
  jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Small JavaScript module for the documentation.
 | 
			
		||||
 */
 | 
			
		||||
var Documentation = {
 | 
			
		||||
 | 
			
		||||
  init : function() {
 | 
			
		||||
    this.fixFirefoxAnchorBug();
 | 
			
		||||
    this.highlightSearchWords();
 | 
			
		||||
    this.initIndexTable();
 | 
			
		||||
    this.initOnKeyListeners();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * i18n support
 | 
			
		||||
   */
 | 
			
		||||
  TRANSLATIONS : {},
 | 
			
		||||
  PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
 | 
			
		||||
  LOCALE : 'unknown',
 | 
			
		||||
 | 
			
		||||
  // gettext and ngettext don't access this so that the functions
 | 
			
		||||
  // can safely bound to a different name (_ = Documentation.gettext)
 | 
			
		||||
  gettext : function(string) {
 | 
			
		||||
    var translated = Documentation.TRANSLATIONS[string];
 | 
			
		||||
    if (typeof translated === 'undefined')
 | 
			
		||||
      return string;
 | 
			
		||||
    return (typeof translated === 'string') ? translated : translated[0];
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  ngettext : function(singular, plural, n) {
 | 
			
		||||
    var translated = Documentation.TRANSLATIONS[singular];
 | 
			
		||||
    if (typeof translated === 'undefined')
 | 
			
		||||
      return (n == 1) ? singular : plural;
 | 
			
		||||
    return translated[Documentation.PLURALEXPR(n)];
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  addTranslations : function(catalog) {
 | 
			
		||||
    for (var key in catalog.messages)
 | 
			
		||||
      this.TRANSLATIONS[key] = catalog.messages[key];
 | 
			
		||||
    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
 | 
			
		||||
    this.LOCALE = catalog.locale;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * add context elements like header anchor links
 | 
			
		||||
   */
 | 
			
		||||
  addContextElements : function() {
 | 
			
		||||
    $('div[id] > :header:first').each(function() {
 | 
			
		||||
      $('<a class="headerlink">\u00B6</a>').
 | 
			
		||||
      attr('href', '#' + this.id).
 | 
			
		||||
      attr('title', _('Permalink to this headline')).
 | 
			
		||||
      appendTo(this);
 | 
			
		||||
    });
 | 
			
		||||
    $('dt[id]').each(function() {
 | 
			
		||||
      $('<a class="headerlink">\u00B6</a>').
 | 
			
		||||
      attr('href', '#' + this.id).
 | 
			
		||||
      attr('title', _('Permalink to this definition')).
 | 
			
		||||
      appendTo(this);
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * workaround a firefox stupidity
 | 
			
		||||
   * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
 | 
			
		||||
   */
 | 
			
		||||
  fixFirefoxAnchorBug : function() {
 | 
			
		||||
    if (document.location.hash && $.browser.mozilla)
 | 
			
		||||
      window.setTimeout(function() {
 | 
			
		||||
        document.location.href += '';
 | 
			
		||||
      }, 10);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * highlight the search words provided in the url in the text
 | 
			
		||||
   */
 | 
			
		||||
  highlightSearchWords : function() {
 | 
			
		||||
    var params = $.getQueryParameters();
 | 
			
		||||
    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
 | 
			
		||||
    if (terms.length) {
 | 
			
		||||
      var body = $('div.body');
 | 
			
		||||
      if (!body.length) {
 | 
			
		||||
        body = $('body');
 | 
			
		||||
      }
 | 
			
		||||
      window.setTimeout(function() {
 | 
			
		||||
        $.each(terms, function() {
 | 
			
		||||
          body.highlightText(this.toLowerCase(), 'highlighted');
 | 
			
		||||
        });
 | 
			
		||||
      }, 10);
 | 
			
		||||
      $('<p class="highlight-link"><a href="javascript:Documentation.' +
 | 
			
		||||
        'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
 | 
			
		||||
          .appendTo($('#searchbox'));
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * init the domain index toggle buttons
 | 
			
		||||
   */
 | 
			
		||||
  initIndexTable : function() {
 | 
			
		||||
    var togglers = $('img.toggler').click(function() {
 | 
			
		||||
      var src = $(this).attr('src');
 | 
			
		||||
      var idnum = $(this).attr('id').substr(7);
 | 
			
		||||
      $('tr.cg-' + idnum).toggle();
 | 
			
		||||
      if (src.substr(-9) === 'minus.png')
 | 
			
		||||
        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
 | 
			
		||||
      else
 | 
			
		||||
        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
 | 
			
		||||
    }).css('display', '');
 | 
			
		||||
    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
 | 
			
		||||
        togglers.click();
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * helper function to hide the search marks again
 | 
			
		||||
   */
 | 
			
		||||
  hideSearchWords : function() {
 | 
			
		||||
    $('#searchbox .highlight-link').fadeOut(300);
 | 
			
		||||
    $('span.highlighted').removeClass('highlighted');
 | 
			
		||||
    var url = new URL(window.location);
 | 
			
		||||
    url.searchParams.delete('highlight');
 | 
			
		||||
    window.history.replaceState({}, '', url);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
   * helper function to focus on search bar
 | 
			
		||||
   */
 | 
			
		||||
  focusSearchBar : function() {
 | 
			
		||||
    $('input[name=q]').first().focus();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * make the url absolute
 | 
			
		||||
   */
 | 
			
		||||
  makeURL : function(relativeURL) {
 | 
			
		||||
    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * get the current relative url
 | 
			
		||||
   */
 | 
			
		||||
  getCurrentURL : function() {
 | 
			
		||||
    var path = document.location.pathname;
 | 
			
		||||
    var parts = path.split(/\//);
 | 
			
		||||
    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
 | 
			
		||||
      if (this === '..')
 | 
			
		||||
        parts.pop();
 | 
			
		||||
    });
 | 
			
		||||
    var url = parts.join('/');
 | 
			
		||||
    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  initOnKeyListeners: function() {
 | 
			
		||||
    // only install a listener if it is really needed
 | 
			
		||||
    if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
 | 
			
		||||
        !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    $(document).keydown(function(event) {
 | 
			
		||||
      var activeElementType = document.activeElement.tagName;
 | 
			
		||||
      // don't navigate when in search box, textarea, dropdown or button
 | 
			
		||||
      if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
 | 
			
		||||
          && activeElementType !== 'BUTTON') {
 | 
			
		||||
        if (event.altKey || event.ctrlKey || event.metaKey)
 | 
			
		||||
          return;
 | 
			
		||||
 | 
			
		||||
          if (!event.shiftKey) {
 | 
			
		||||
            switch (event.key) {
 | 
			
		||||
              case 'ArrowLeft':
 | 
			
		||||
                if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS)
 | 
			
		||||
                  break;
 | 
			
		||||
                var prevHref = $('link[rel="prev"]').prop('href');
 | 
			
		||||
                if (prevHref) {
 | 
			
		||||
                  window.location.href = prevHref;
 | 
			
		||||
                  return false;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
              case 'ArrowRight':
 | 
			
		||||
                if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS)
 | 
			
		||||
                  break;
 | 
			
		||||
                var nextHref = $('link[rel="next"]').prop('href');
 | 
			
		||||
                if (nextHref) {
 | 
			
		||||
                  window.location.href = nextHref;
 | 
			
		||||
                  return false;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
              case 'Escape':
 | 
			
		||||
                if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
 | 
			
		||||
                  break;
 | 
			
		||||
                Documentation.hideSearchWords();
 | 
			
		||||
                return false;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // some keyboard layouts may need Shift to get /
 | 
			
		||||
        switch (event.key) {
 | 
			
		||||
          case '/':
 | 
			
		||||
            if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
 | 
			
		||||
              break;
 | 
			
		||||
            Documentation.focusSearchBar();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// quick alias for translations
 | 
			
		||||
_ = Documentation.gettext;
 | 
			
		||||
 | 
			
		||||
$(document).ready(function() {
 | 
			
		||||
  Documentation.init();
 | 
			
		||||
});
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
var DOCUMENTATION_OPTIONS = {
 | 
			
		||||
    URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
 | 
			
		||||
    VERSION: '2.0.0',
 | 
			
		||||
    LANGUAGE: 'None',
 | 
			
		||||
    COLLAPSE_INDEX: false,
 | 
			
		||||
    BUILDER: 'html',
 | 
			
		||||
    FILE_SUFFIX: '.html',
 | 
			
		||||
    LINK_SUFFIX: '.html',
 | 
			
		||||
    HAS_SOURCE: true,
 | 
			
		||||
    SOURCELINK_SUFFIX: '.txt',
 | 
			
		||||
    NAVIGATION_WITH_KEYS: false,
 | 
			
		||||
    SHOW_SEARCH_SUMMARY: true,
 | 
			
		||||
    ENABLE_SEARCH_SHORTCUTS: true,
 | 
			
		||||
};
 | 
			
		||||
| 
		 After Width: | Height: | Size: 286 B  | 
							
								
								
									
										10872
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/_static/jquery-3.5.1.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										2
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/_static/jquery.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
			
		||||
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
 | 
			
		||||
							
								
								
									
										4
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/_static/js/html5shiv-printshiv.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
 | 
			
		||||
*/
 | 
			
		||||
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
 | 
			
		||||
							
								
								
									
										4
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/_static/js/html5shiv.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
 | 
			
		||||
*/
 | 
			
		||||
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
 | 
			
		||||
@@ -0,0 +1,297 @@
 | 
			
		||||
/*
 | 
			
		||||
 * language_data.js
 | 
			
		||||
 * ~~~~~~~~~~~~~~~~
 | 
			
		||||
 *
 | 
			
		||||
 * This script contains the language-specific data used by searchtools.js,
 | 
			
		||||
 * namely the list of stopwords, stemmer, scorer and splitter.
 | 
			
		||||
 *
 | 
			
		||||
 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
 | 
			
		||||
 * :license: BSD, see LICENSE for details.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Non-minified version is copied as a separate JS file, is available */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Porter Stemmer
 | 
			
		||||
 */
 | 
			
		||||
var Stemmer = function() {
 | 
			
		||||
 | 
			
		||||
  var step2list = {
 | 
			
		||||
    ational: 'ate',
 | 
			
		||||
    tional: 'tion',
 | 
			
		||||
    enci: 'ence',
 | 
			
		||||
    anci: 'ance',
 | 
			
		||||
    izer: 'ize',
 | 
			
		||||
    bli: 'ble',
 | 
			
		||||
    alli: 'al',
 | 
			
		||||
    entli: 'ent',
 | 
			
		||||
    eli: 'e',
 | 
			
		||||
    ousli: 'ous',
 | 
			
		||||
    ization: 'ize',
 | 
			
		||||
    ation: 'ate',
 | 
			
		||||
    ator: 'ate',
 | 
			
		||||
    alism: 'al',
 | 
			
		||||
    iveness: 'ive',
 | 
			
		||||
    fulness: 'ful',
 | 
			
		||||
    ousness: 'ous',
 | 
			
		||||
    aliti: 'al',
 | 
			
		||||
    iviti: 'ive',
 | 
			
		||||
    biliti: 'ble',
 | 
			
		||||
    logi: 'log'
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  var step3list = {
 | 
			
		||||
    icate: 'ic',
 | 
			
		||||
    ative: '',
 | 
			
		||||
    alize: 'al',
 | 
			
		||||
    iciti: 'ic',
 | 
			
		||||
    ical: 'ic',
 | 
			
		||||
    ful: '',
 | 
			
		||||
    ness: ''
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  var c = "[^aeiou]";          // consonant
 | 
			
		||||
  var v = "[aeiouy]";          // vowel
 | 
			
		||||
  var C = c + "[^aeiouy]*";    // consonant sequence
 | 
			
		||||
  var V = v + "[aeiou]*";      // vowel sequence
 | 
			
		||||
 | 
			
		||||
  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
 | 
			
		||||
  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
 | 
			
		||||
  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
 | 
			
		||||
  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
 | 
			
		||||
 | 
			
		||||
  this.stemWord = function (w) {
 | 
			
		||||
    var stem;
 | 
			
		||||
    var suffix;
 | 
			
		||||
    var firstch;
 | 
			
		||||
    var origword = w;
 | 
			
		||||
 | 
			
		||||
    if (w.length < 3)
 | 
			
		||||
      return w;
 | 
			
		||||
 | 
			
		||||
    var re;
 | 
			
		||||
    var re2;
 | 
			
		||||
    var re3;
 | 
			
		||||
    var re4;
 | 
			
		||||
 | 
			
		||||
    firstch = w.substr(0,1);
 | 
			
		||||
    if (firstch == "y")
 | 
			
		||||
      w = firstch.toUpperCase() + w.substr(1);
 | 
			
		||||
 | 
			
		||||
    // Step 1a
 | 
			
		||||
    re = /^(.+?)(ss|i)es$/;
 | 
			
		||||
    re2 = /^(.+?)([^s])s$/;
 | 
			
		||||
 | 
			
		||||
    if (re.test(w))
 | 
			
		||||
      w = w.replace(re,"$1$2");
 | 
			
		||||
    else if (re2.test(w))
 | 
			
		||||
      w = w.replace(re2,"$1$2");
 | 
			
		||||
 | 
			
		||||
    // Step 1b
 | 
			
		||||
    re = /^(.+?)eed$/;
 | 
			
		||||
    re2 = /^(.+?)(ed|ing)$/;
 | 
			
		||||
    if (re.test(w)) {
 | 
			
		||||
      var fp = re.exec(w);
 | 
			
		||||
      re = new RegExp(mgr0);
 | 
			
		||||
      if (re.test(fp[1])) {
 | 
			
		||||
        re = /.$/;
 | 
			
		||||
        w = w.replace(re,"");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else if (re2.test(w)) {
 | 
			
		||||
      var fp = re2.exec(w);
 | 
			
		||||
      stem = fp[1];
 | 
			
		||||
      re2 = new RegExp(s_v);
 | 
			
		||||
      if (re2.test(stem)) {
 | 
			
		||||
        w = stem;
 | 
			
		||||
        re2 = /(at|bl|iz)$/;
 | 
			
		||||
        re3 = new RegExp("([^aeiouylsz])\\1$");
 | 
			
		||||
        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
 | 
			
		||||
        if (re2.test(w))
 | 
			
		||||
          w = w + "e";
 | 
			
		||||
        else if (re3.test(w)) {
 | 
			
		||||
          re = /.$/;
 | 
			
		||||
          w = w.replace(re,"");
 | 
			
		||||
        }
 | 
			
		||||
        else if (re4.test(w))
 | 
			
		||||
          w = w + "e";
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Step 1c
 | 
			
		||||
    re = /^(.+?)y$/;
 | 
			
		||||
    if (re.test(w)) {
 | 
			
		||||
      var fp = re.exec(w);
 | 
			
		||||
      stem = fp[1];
 | 
			
		||||
      re = new RegExp(s_v);
 | 
			
		||||
      if (re.test(stem))
 | 
			
		||||
        w = stem + "i";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Step 2
 | 
			
		||||
    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
 | 
			
		||||
    if (re.test(w)) {
 | 
			
		||||
      var fp = re.exec(w);
 | 
			
		||||
      stem = fp[1];
 | 
			
		||||
      suffix = fp[2];
 | 
			
		||||
      re = new RegExp(mgr0);
 | 
			
		||||
      if (re.test(stem))
 | 
			
		||||
        w = stem + step2list[suffix];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Step 3
 | 
			
		||||
    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
 | 
			
		||||
    if (re.test(w)) {
 | 
			
		||||
      var fp = re.exec(w);
 | 
			
		||||
      stem = fp[1];
 | 
			
		||||
      suffix = fp[2];
 | 
			
		||||
      re = new RegExp(mgr0);
 | 
			
		||||
      if (re.test(stem))
 | 
			
		||||
        w = stem + step3list[suffix];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Step 4
 | 
			
		||||
    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
 | 
			
		||||
    re2 = /^(.+?)(s|t)(ion)$/;
 | 
			
		||||
    if (re.test(w)) {
 | 
			
		||||
      var fp = re.exec(w);
 | 
			
		||||
      stem = fp[1];
 | 
			
		||||
      re = new RegExp(mgr1);
 | 
			
		||||
      if (re.test(stem))
 | 
			
		||||
        w = stem;
 | 
			
		||||
    }
 | 
			
		||||
    else if (re2.test(w)) {
 | 
			
		||||
      var fp = re2.exec(w);
 | 
			
		||||
      stem = fp[1] + fp[2];
 | 
			
		||||
      re2 = new RegExp(mgr1);
 | 
			
		||||
      if (re2.test(stem))
 | 
			
		||||
        w = stem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Step 5
 | 
			
		||||
    re = /^(.+?)e$/;
 | 
			
		||||
    if (re.test(w)) {
 | 
			
		||||
      var fp = re.exec(w);
 | 
			
		||||
      stem = fp[1];
 | 
			
		||||
      re = new RegExp(mgr1);
 | 
			
		||||
      re2 = new RegExp(meq1);
 | 
			
		||||
      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
 | 
			
		||||
      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
 | 
			
		||||
        w = stem;
 | 
			
		||||
    }
 | 
			
		||||
    re = /ll$/;
 | 
			
		||||
    re2 = new RegExp(mgr1);
 | 
			
		||||
    if (re.test(w) && re2.test(w)) {
 | 
			
		||||
      re = /.$/;
 | 
			
		||||
      w = w.replace(re,"");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // and turn initial Y back to y
 | 
			
		||||
    if (firstch == "y")
 | 
			
		||||
      w = firstch.toLowerCase() + w.substr(1);
 | 
			
		||||
    return w;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var splitChars = (function() {
 | 
			
		||||
    var result = {};
 | 
			
		||||
    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
 | 
			
		||||
         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
 | 
			
		||||
         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
 | 
			
		||||
         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
 | 
			
		||||
         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
 | 
			
		||||
         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
 | 
			
		||||
         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
 | 
			
		||||
         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
 | 
			
		||||
         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
 | 
			
		||||
         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
 | 
			
		||||
    var i, j, start, end;
 | 
			
		||||
    for (i = 0; i < singles.length; i++) {
 | 
			
		||||
        result[singles[i]] = true;
 | 
			
		||||
    }
 | 
			
		||||
    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
 | 
			
		||||
         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
 | 
			
		||||
         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
 | 
			
		||||
         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
 | 
			
		||||
         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
 | 
			
		||||
         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
 | 
			
		||||
         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
 | 
			
		||||
         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
 | 
			
		||||
         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
 | 
			
		||||
         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
 | 
			
		||||
         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
 | 
			
		||||
         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
 | 
			
		||||
         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
 | 
			
		||||
         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
 | 
			
		||||
         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
 | 
			
		||||
         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
 | 
			
		||||
         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
 | 
			
		||||
         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
 | 
			
		||||
         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
 | 
			
		||||
         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
 | 
			
		||||
         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
 | 
			
		||||
         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
 | 
			
		||||
         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
 | 
			
		||||
         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
 | 
			
		||||
         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
 | 
			
		||||
         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
 | 
			
		||||
         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
 | 
			
		||||
         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
 | 
			
		||||
         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
 | 
			
		||||
         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
 | 
			
		||||
         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
 | 
			
		||||
         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
 | 
			
		||||
         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
 | 
			
		||||
         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
 | 
			
		||||
         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
 | 
			
		||||
         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
 | 
			
		||||
         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
 | 
			
		||||
         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
 | 
			
		||||
         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
 | 
			
		||||
         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
 | 
			
		||||
         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
 | 
			
		||||
         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
 | 
			
		||||
         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
 | 
			
		||||
         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
 | 
			
		||||
         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
 | 
			
		||||
         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
 | 
			
		||||
         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
 | 
			
		||||
         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
 | 
			
		||||
         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
 | 
			
		||||
    for (i = 0; i < ranges.length; i++) {
 | 
			
		||||
        start = ranges[i][0];
 | 
			
		||||
        end = ranges[i][1];
 | 
			
		||||
        for (j = start; j <= end; j++) {
 | 
			
		||||
            result[j] = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
function splitQuery(query) {
 | 
			
		||||
    var result = [];
 | 
			
		||||
    var start = -1;
 | 
			
		||||
    for (var i = 0; i < query.length; i++) {
 | 
			
		||||
        if (splitChars[query.charCodeAt(i)]) {
 | 
			
		||||
            if (start !== -1) {
 | 
			
		||||
                result.push(query.slice(start, i));
 | 
			
		||||
                start = -1;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (start === -1) {
 | 
			
		||||
            start = i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (start !== -1) {
 | 
			
		||||
        result.push(query.slice(start));
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
		 After Width: | Height: | Size: 90 B  | 
| 
		 After Width: | Height: | Size: 90 B  | 
@@ -0,0 +1,74 @@
 | 
			
		||||
pre { line-height: 125%; }
 | 
			
		||||
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
 | 
			
		||||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
 | 
			
		||||
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
 | 
			
		||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
 | 
			
		||||
.highlight .hll { background-color: #ffffcc }
 | 
			
		||||
.highlight { background: #f8f8f8; }
 | 
			
		||||
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
 | 
			
		||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
 | 
			
		||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
 | 
			
		||||
.highlight .o { color: #666666 } /* Operator */
 | 
			
		||||
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
 | 
			
		||||
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
 | 
			
		||||
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
 | 
			
		||||
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
 | 
			
		||||
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
 | 
			
		||||
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
 | 
			
		||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
 | 
			
		||||
.highlight .ge { font-style: italic } /* Generic.Emph */
 | 
			
		||||
.highlight .gr { color: #E40000 } /* Generic.Error */
 | 
			
		||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
 | 
			
		||||
.highlight .gi { color: #008400 } /* Generic.Inserted */
 | 
			
		||||
.highlight .go { color: #717171 } /* Generic.Output */
 | 
			
		||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
 | 
			
		||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
 | 
			
		||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
 | 
			
		||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
 | 
			
		||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
 | 
			
		||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
 | 
			
		||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
 | 
			
		||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
 | 
			
		||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
 | 
			
		||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
 | 
			
		||||
.highlight .m { color: #666666 } /* Literal.Number */
 | 
			
		||||
.highlight .s { color: #BA2121 } /* Literal.String */
 | 
			
		||||
.highlight .na { color: #687822 } /* Name.Attribute */
 | 
			
		||||
.highlight .nb { color: #008000 } /* Name.Builtin */
 | 
			
		||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
 | 
			
		||||
.highlight .no { color: #880000 } /* Name.Constant */
 | 
			
		||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
 | 
			
		||||
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
 | 
			
		||||
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
 | 
			
		||||
.highlight .nf { color: #0000FF } /* Name.Function */
 | 
			
		||||
.highlight .nl { color: #767600 } /* Name.Label */
 | 
			
		||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
 | 
			
		||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
 | 
			
		||||
.highlight .nv { color: #19177C } /* Name.Variable */
 | 
			
		||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
 | 
			
		||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
 | 
			
		||||
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
 | 
			
		||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
 | 
			
		||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
 | 
			
		||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
 | 
			
		||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
 | 
			
		||||
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
 | 
			
		||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
 | 
			
		||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
 | 
			
		||||
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
 | 
			
		||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
 | 
			
		||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
 | 
			
		||||
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
 | 
			
		||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
 | 
			
		||||
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
 | 
			
		||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
 | 
			
		||||
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
 | 
			
		||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
 | 
			
		||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
 | 
			
		||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
 | 
			
		||||
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
 | 
			
		||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
 | 
			
		||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
 | 
			
		||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
 | 
			
		||||
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
 | 
			
		||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
 | 
			
		||||
@@ -0,0 +1,525 @@
 | 
			
		||||
/*
 | 
			
		||||
 * searchtools.js
 | 
			
		||||
 * ~~~~~~~~~~~~~~~~
 | 
			
		||||
 *
 | 
			
		||||
 * Sphinx JavaScript utilities for the full-text search.
 | 
			
		||||
 *
 | 
			
		||||
 * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
 | 
			
		||||
 * :license: BSD, see LICENSE for details.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
if (!Scorer) {
 | 
			
		||||
  /**
 | 
			
		||||
   * Simple result scoring code.
 | 
			
		||||
   */
 | 
			
		||||
  var Scorer = {
 | 
			
		||||
    // Implement the following function to further tweak the score for each result
 | 
			
		||||
    // The function takes a result array [filename, title, anchor, descr, score]
 | 
			
		||||
    // and returns the new score.
 | 
			
		||||
    /*
 | 
			
		||||
    score: function(result) {
 | 
			
		||||
      return result[4];
 | 
			
		||||
    },
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    // query matches the full name of an object
 | 
			
		||||
    objNameMatch: 11,
 | 
			
		||||
    // or matches in the last dotted part of the object name
 | 
			
		||||
    objPartialMatch: 6,
 | 
			
		||||
    // Additive scores depending on the priority of the object
 | 
			
		||||
    objPrio: {0:  15,   // used to be importantResults
 | 
			
		||||
              1:  5,   // used to be objectResults
 | 
			
		||||
              2: -5},  // used to be unimportantResults
 | 
			
		||||
    //  Used when the priority is not in the mapping.
 | 
			
		||||
    objPrioDefault: 0,
 | 
			
		||||
 | 
			
		||||
    // query found in title
 | 
			
		||||
    title: 15,
 | 
			
		||||
    partialTitle: 7,
 | 
			
		||||
    // query found in terms
 | 
			
		||||
    term: 5,
 | 
			
		||||
    partialTerm: 2
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!splitQuery) {
 | 
			
		||||
  function splitQuery(query) {
 | 
			
		||||
    return query.split(/\s+/);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Search Module
 | 
			
		||||
 */
 | 
			
		||||
var Search = {
 | 
			
		||||
 | 
			
		||||
  _index : null,
 | 
			
		||||
  _queued_query : null,
 | 
			
		||||
  _pulse_status : -1,
 | 
			
		||||
 | 
			
		||||
  htmlToText : function(htmlString) {
 | 
			
		||||
      var virtualDocument = document.implementation.createHTMLDocument('virtual');
 | 
			
		||||
      var htmlElement = $(htmlString, virtualDocument);
 | 
			
		||||
      htmlElement.find('.headerlink').remove();
 | 
			
		||||
      docContent = htmlElement.find('[role=main]')[0];
 | 
			
		||||
      if(docContent === undefined) {
 | 
			
		||||
          console.warn("Content block not found. Sphinx search tries to obtain it " +
 | 
			
		||||
                       "via '[role=main]'. Could you check your theme or template.");
 | 
			
		||||
          return "";
 | 
			
		||||
      }
 | 
			
		||||
      return docContent.textContent || docContent.innerText;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  init : function() {
 | 
			
		||||
      var params = $.getQueryParameters();
 | 
			
		||||
      if (params.q) {
 | 
			
		||||
          var query = params.q[0];
 | 
			
		||||
          $('input[name="q"]')[0].value = query;
 | 
			
		||||
          this.performSearch(query);
 | 
			
		||||
      }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  loadIndex : function(url) {
 | 
			
		||||
    $.ajax({type: "GET", url: url, data: null,
 | 
			
		||||
            dataType: "script", cache: true,
 | 
			
		||||
            complete: function(jqxhr, textstatus) {
 | 
			
		||||
              if (textstatus != "success") {
 | 
			
		||||
                document.getElementById("searchindexloader").src = url;
 | 
			
		||||
              }
 | 
			
		||||
            }});
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  setIndex : function(index) {
 | 
			
		||||
    var q;
 | 
			
		||||
    this._index = index;
 | 
			
		||||
    if ((q = this._queued_query) !== null) {
 | 
			
		||||
      this._queued_query = null;
 | 
			
		||||
      Search.query(q);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  hasIndex : function() {
 | 
			
		||||
      return this._index !== null;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  deferQuery : function(query) {
 | 
			
		||||
      this._queued_query = query;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  stopPulse : function() {
 | 
			
		||||
      this._pulse_status = 0;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  startPulse : function() {
 | 
			
		||||
    if (this._pulse_status >= 0)
 | 
			
		||||
        return;
 | 
			
		||||
    function pulse() {
 | 
			
		||||
      var i;
 | 
			
		||||
      Search._pulse_status = (Search._pulse_status + 1) % 4;
 | 
			
		||||
      var dotString = '';
 | 
			
		||||
      for (i = 0; i < Search._pulse_status; i++)
 | 
			
		||||
        dotString += '.';
 | 
			
		||||
      Search.dots.text(dotString);
 | 
			
		||||
      if (Search._pulse_status > -1)
 | 
			
		||||
        window.setTimeout(pulse, 500);
 | 
			
		||||
    }
 | 
			
		||||
    pulse();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * perform a search for something (or wait until index is loaded)
 | 
			
		||||
   */
 | 
			
		||||
  performSearch : function(query) {
 | 
			
		||||
    // create the required interface elements
 | 
			
		||||
    this.out = $('#search-results');
 | 
			
		||||
    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
 | 
			
		||||
    this.dots = $('<span></span>').appendTo(this.title);
 | 
			
		||||
    this.status = $('<p class="search-summary"> </p>').appendTo(this.out);
 | 
			
		||||
    this.output = $('<ul class="search"/>').appendTo(this.out);
 | 
			
		||||
 | 
			
		||||
    $('#search-progress').text(_('Preparing search...'));
 | 
			
		||||
    this.startPulse();
 | 
			
		||||
 | 
			
		||||
    // index already loaded, the browser was quick!
 | 
			
		||||
    if (this.hasIndex())
 | 
			
		||||
      this.query(query);
 | 
			
		||||
    else
 | 
			
		||||
      this.deferQuery(query);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * execute search (requires search index to be loaded)
 | 
			
		||||
   */
 | 
			
		||||
  query : function(query) {
 | 
			
		||||
    var i;
 | 
			
		||||
 | 
			
		||||
    // stem the searchterms and add them to the correct list
 | 
			
		||||
    var stemmer = new Stemmer();
 | 
			
		||||
    var searchterms = [];
 | 
			
		||||
    var excluded = [];
 | 
			
		||||
    var hlterms = [];
 | 
			
		||||
    var tmp = splitQuery(query);
 | 
			
		||||
    var objectterms = [];
 | 
			
		||||
    for (i = 0; i < tmp.length; i++) {
 | 
			
		||||
      if (tmp[i] !== "") {
 | 
			
		||||
          objectterms.push(tmp[i].toLowerCase());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
 | 
			
		||||
        // skip this "word"
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      // stem the word
 | 
			
		||||
      var word = stemmer.stemWord(tmp[i].toLowerCase());
 | 
			
		||||
      var toAppend;
 | 
			
		||||
      // select the correct list
 | 
			
		||||
      if (word[0] == '-') {
 | 
			
		||||
        toAppend = excluded;
 | 
			
		||||
        word = word.substr(1);
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        toAppend = searchterms;
 | 
			
		||||
        hlterms.push(tmp[i].toLowerCase());
 | 
			
		||||
      }
 | 
			
		||||
      // only add if not already in the list
 | 
			
		||||
      if (!$u.contains(toAppend, word))
 | 
			
		||||
        toAppend.push(word);
 | 
			
		||||
    }
 | 
			
		||||
    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
 | 
			
		||||
 | 
			
		||||
    // console.debug('SEARCH: searching for:');
 | 
			
		||||
    // console.info('required: ', searchterms);
 | 
			
		||||
    // console.info('excluded: ', excluded);
 | 
			
		||||
 | 
			
		||||
    // prepare search
 | 
			
		||||
    var terms = this._index.terms;
 | 
			
		||||
    var titleterms = this._index.titleterms;
 | 
			
		||||
 | 
			
		||||
    // array of [filename, title, anchor, descr, score]
 | 
			
		||||
    var results = [];
 | 
			
		||||
    $('#search-progress').empty();
 | 
			
		||||
 | 
			
		||||
    // lookup as object
 | 
			
		||||
    for (i = 0; i < objectterms.length; i++) {
 | 
			
		||||
      var others = [].concat(objectterms.slice(0, i),
 | 
			
		||||
                             objectterms.slice(i+1, objectterms.length));
 | 
			
		||||
      results = results.concat(this.performObjectSearch(objectterms[i], others));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // lookup as search terms in fulltext
 | 
			
		||||
    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
 | 
			
		||||
 | 
			
		||||
    // let the scorer override scores with a custom scoring function
 | 
			
		||||
    if (Scorer.score) {
 | 
			
		||||
      for (i = 0; i < results.length; i++)
 | 
			
		||||
        results[i][4] = Scorer.score(results[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // now sort the results by score (in opposite order of appearance, since the
 | 
			
		||||
    // display function below uses pop() to retrieve items) and then
 | 
			
		||||
    // alphabetically
 | 
			
		||||
    results.sort(function(a, b) {
 | 
			
		||||
      var left = a[4];
 | 
			
		||||
      var right = b[4];
 | 
			
		||||
      if (left > right) {
 | 
			
		||||
        return 1;
 | 
			
		||||
      } else if (left < right) {
 | 
			
		||||
        return -1;
 | 
			
		||||
      } else {
 | 
			
		||||
        // same score: sort alphabetically
 | 
			
		||||
        left = a[1].toLowerCase();
 | 
			
		||||
        right = b[1].toLowerCase();
 | 
			
		||||
        return (left > right) ? -1 : ((left < right) ? 1 : 0);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // for debugging
 | 
			
		||||
    //Search.lastresults = results.slice();  // a copy
 | 
			
		||||
    //console.info('search results:', Search.lastresults);
 | 
			
		||||
 | 
			
		||||
    // print(the results
 | 
			
		||||
    var resultCount = results.length;
 | 
			
		||||
    function displayNextItem() {
 | 
			
		||||
      // results left, load the summary and display it
 | 
			
		||||
      if (results.length) {
 | 
			
		||||
        var item = results.pop();
 | 
			
		||||
        var listItem = $('<li></li>');
 | 
			
		||||
        var requestUrl = "";
 | 
			
		||||
        var linkUrl = "";
 | 
			
		||||
        if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
 | 
			
		||||
          // dirhtml builder
 | 
			
		||||
          var dirname = item[0] + '/';
 | 
			
		||||
          if (dirname.match(/\/index\/$/)) {
 | 
			
		||||
            dirname = dirname.substring(0, dirname.length-6);
 | 
			
		||||
          } else if (dirname == 'index/') {
 | 
			
		||||
            dirname = '';
 | 
			
		||||
          }
 | 
			
		||||
          requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
 | 
			
		||||
          linkUrl = requestUrl;
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
          // normal html builders
 | 
			
		||||
          requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
 | 
			
		||||
          linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
 | 
			
		||||
        }
 | 
			
		||||
        listItem.append($('<a/>').attr('href',
 | 
			
		||||
            linkUrl +
 | 
			
		||||
            highlightstring + item[2]).html(item[1]));
 | 
			
		||||
        if (item[3]) {
 | 
			
		||||
          listItem.append($('<span> (' + item[3] + ')</span>'));
 | 
			
		||||
          Search.output.append(listItem);
 | 
			
		||||
          setTimeout(function() {
 | 
			
		||||
            displayNextItem();
 | 
			
		||||
          }, 5);
 | 
			
		||||
        } else if (DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY) {
 | 
			
		||||
          $.ajax({url: requestUrl,
 | 
			
		||||
                  dataType: "text",
 | 
			
		||||
                  complete: function(jqxhr, textstatus) {
 | 
			
		||||
                    var data = jqxhr.responseText;
 | 
			
		||||
                    if (data !== '' && data !== undefined) {
 | 
			
		||||
                      var summary = Search.makeSearchSummary(data, searchterms, hlterms);
 | 
			
		||||
                      if (summary) {
 | 
			
		||||
                        listItem.append(summary);
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                    Search.output.append(listItem);
 | 
			
		||||
                    setTimeout(function() {
 | 
			
		||||
                      displayNextItem();
 | 
			
		||||
                    }, 5);
 | 
			
		||||
                  }});
 | 
			
		||||
        } else {
 | 
			
		||||
          // just display title
 | 
			
		||||
          Search.output.append(listItem);
 | 
			
		||||
          setTimeout(function() {
 | 
			
		||||
            displayNextItem();
 | 
			
		||||
          }, 5);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // search finished, update title and status message
 | 
			
		||||
      else {
 | 
			
		||||
        Search.stopPulse();
 | 
			
		||||
        Search.title.text(_('Search Results'));
 | 
			
		||||
        if (!resultCount)
 | 
			
		||||
          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
 | 
			
		||||
        else
 | 
			
		||||
            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
 | 
			
		||||
        Search.status.fadeIn(500);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    displayNextItem();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * search for object names
 | 
			
		||||
   */
 | 
			
		||||
  performObjectSearch : function(object, otherterms) {
 | 
			
		||||
    var filenames = this._index.filenames;
 | 
			
		||||
    var docnames = this._index.docnames;
 | 
			
		||||
    var objects = this._index.objects;
 | 
			
		||||
    var objnames = this._index.objnames;
 | 
			
		||||
    var titles = this._index.titles;
 | 
			
		||||
 | 
			
		||||
    var i;
 | 
			
		||||
    var results = [];
 | 
			
		||||
 | 
			
		||||
    for (var prefix in objects) {
 | 
			
		||||
      for (var iMatch = 0; iMatch != objects[prefix].length; ++iMatch) {
 | 
			
		||||
        var match = objects[prefix][iMatch];
 | 
			
		||||
        var name = match[4];
 | 
			
		||||
        var fullname = (prefix ? prefix + '.' : '') + name;
 | 
			
		||||
        var fullnameLower = fullname.toLowerCase()
 | 
			
		||||
        if (fullnameLower.indexOf(object) > -1) {
 | 
			
		||||
          var score = 0;
 | 
			
		||||
          var parts = fullnameLower.split('.');
 | 
			
		||||
          // check for different match types: exact matches of full name or
 | 
			
		||||
          // "last name" (i.e. last dotted part)
 | 
			
		||||
          if (fullnameLower == object || parts[parts.length - 1] == object) {
 | 
			
		||||
            score += Scorer.objNameMatch;
 | 
			
		||||
          // matches in last name
 | 
			
		||||
          } else if (parts[parts.length - 1].indexOf(object) > -1) {
 | 
			
		||||
            score += Scorer.objPartialMatch;
 | 
			
		||||
          }
 | 
			
		||||
          var objname = objnames[match[1]][2];
 | 
			
		||||
          var title = titles[match[0]];
 | 
			
		||||
          // If more than one term searched for, we require other words to be
 | 
			
		||||
          // found in the name/title/description
 | 
			
		||||
          if (otherterms.length > 0) {
 | 
			
		||||
            var haystack = (prefix + ' ' + name + ' ' +
 | 
			
		||||
                            objname + ' ' + title).toLowerCase();
 | 
			
		||||
            var allfound = true;
 | 
			
		||||
            for (i = 0; i < otherterms.length; i++) {
 | 
			
		||||
              if (haystack.indexOf(otherterms[i]) == -1) {
 | 
			
		||||
                allfound = false;
 | 
			
		||||
                break;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            if (!allfound) {
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          var descr = objname + _(', in ') + title;
 | 
			
		||||
 | 
			
		||||
          var anchor = match[3];
 | 
			
		||||
          if (anchor === '')
 | 
			
		||||
            anchor = fullname;
 | 
			
		||||
          else if (anchor == '-')
 | 
			
		||||
            anchor = objnames[match[1]][1] + '-' + fullname;
 | 
			
		||||
          // add custom score for some objects according to scorer
 | 
			
		||||
          if (Scorer.objPrio.hasOwnProperty(match[2])) {
 | 
			
		||||
            score += Scorer.objPrio[match[2]];
 | 
			
		||||
          } else {
 | 
			
		||||
            score += Scorer.objPrioDefault;
 | 
			
		||||
          }
 | 
			
		||||
          results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return results;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
 | 
			
		||||
   */
 | 
			
		||||
  escapeRegExp : function(string) {
 | 
			
		||||
    return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * search for full-text terms in the index
 | 
			
		||||
   */
 | 
			
		||||
  performTermsSearch : function(searchterms, excluded, terms, titleterms) {
 | 
			
		||||
    var docnames = this._index.docnames;
 | 
			
		||||
    var filenames = this._index.filenames;
 | 
			
		||||
    var titles = this._index.titles;
 | 
			
		||||
 | 
			
		||||
    var i, j, file;
 | 
			
		||||
    var fileMap = {};
 | 
			
		||||
    var scoreMap = {};
 | 
			
		||||
    var results = [];
 | 
			
		||||
 | 
			
		||||
    // perform the search on the required terms
 | 
			
		||||
    for (i = 0; i < searchterms.length; i++) {
 | 
			
		||||
      var word = searchterms[i];
 | 
			
		||||
      var files = [];
 | 
			
		||||
      var _o = [
 | 
			
		||||
        {files: terms[word], score: Scorer.term},
 | 
			
		||||
        {files: titleterms[word], score: Scorer.title}
 | 
			
		||||
      ];
 | 
			
		||||
      // add support for partial matches
 | 
			
		||||
      if (word.length > 2) {
 | 
			
		||||
        var word_regex = this.escapeRegExp(word);
 | 
			
		||||
        for (var w in terms) {
 | 
			
		||||
          if (w.match(word_regex) && !terms[word]) {
 | 
			
		||||
            _o.push({files: terms[w], score: Scorer.partialTerm})
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        for (var w in titleterms) {
 | 
			
		||||
          if (w.match(word_regex) && !titleterms[word]) {
 | 
			
		||||
              _o.push({files: titleterms[w], score: Scorer.partialTitle})
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // no match but word was a required one
 | 
			
		||||
      if ($u.every(_o, function(o){return o.files === undefined;})) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      // found search word in contents
 | 
			
		||||
      $u.each(_o, function(o) {
 | 
			
		||||
        var _files = o.files;
 | 
			
		||||
        if (_files === undefined)
 | 
			
		||||
          return
 | 
			
		||||
 | 
			
		||||
        if (_files.length === undefined)
 | 
			
		||||
          _files = [_files];
 | 
			
		||||
        files = files.concat(_files);
 | 
			
		||||
 | 
			
		||||
        // set score for the word in each file to Scorer.term
 | 
			
		||||
        for (j = 0; j < _files.length; j++) {
 | 
			
		||||
          file = _files[j];
 | 
			
		||||
          if (!(file in scoreMap))
 | 
			
		||||
            scoreMap[file] = {};
 | 
			
		||||
          scoreMap[file][word] = o.score;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // create the mapping
 | 
			
		||||
      for (j = 0; j < files.length; j++) {
 | 
			
		||||
        file = files[j];
 | 
			
		||||
        if (file in fileMap && fileMap[file].indexOf(word) === -1)
 | 
			
		||||
          fileMap[file].push(word);
 | 
			
		||||
        else
 | 
			
		||||
          fileMap[file] = [word];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // now check if the files don't contain excluded terms
 | 
			
		||||
    for (file in fileMap) {
 | 
			
		||||
      var valid = true;
 | 
			
		||||
 | 
			
		||||
      // check if all requirements are matched
 | 
			
		||||
      var filteredTermCount = // as search terms with length < 3 are discarded: ignore
 | 
			
		||||
        searchterms.filter(function(term){return term.length > 2}).length
 | 
			
		||||
      if (
 | 
			
		||||
        fileMap[file].length != searchterms.length &&
 | 
			
		||||
        fileMap[file].length != filteredTermCount
 | 
			
		||||
      ) continue;
 | 
			
		||||
 | 
			
		||||
      // ensure that none of the excluded terms is in the search result
 | 
			
		||||
      for (i = 0; i < excluded.length; i++) {
 | 
			
		||||
        if (terms[excluded[i]] == file ||
 | 
			
		||||
            titleterms[excluded[i]] == file ||
 | 
			
		||||
            $u.contains(terms[excluded[i]] || [], file) ||
 | 
			
		||||
            $u.contains(titleterms[excluded[i]] || [], file)) {
 | 
			
		||||
          valid = false;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // if we have still a valid result we can add it to the result list
 | 
			
		||||
      if (valid) {
 | 
			
		||||
        // select one (max) score for the file.
 | 
			
		||||
        // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
 | 
			
		||||
        var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
 | 
			
		||||
        results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return results;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * helper function to return a node containing the
 | 
			
		||||
   * search summary for a given text. keywords is a list
 | 
			
		||||
   * of stemmed words, hlwords is the list of normal, unstemmed
 | 
			
		||||
   * words. the first one is used to find the occurrence, the
 | 
			
		||||
   * latter for highlighting it.
 | 
			
		||||
   */
 | 
			
		||||
  makeSearchSummary : function(htmlText, keywords, hlwords) {
 | 
			
		||||
    var text = Search.htmlToText(htmlText);
 | 
			
		||||
    if (text == "") {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    var textLower = text.toLowerCase();
 | 
			
		||||
    var start = 0;
 | 
			
		||||
    $.each(keywords, function() {
 | 
			
		||||
      var i = textLower.indexOf(this.toLowerCase());
 | 
			
		||||
      if (i > -1)
 | 
			
		||||
        start = i;
 | 
			
		||||
    });
 | 
			
		||||
    start = Math.max(start - 120, 0);
 | 
			
		||||
    var excerpt = ((start > 0) ? '...' : '') +
 | 
			
		||||
      $.trim(text.substr(start, 240)) +
 | 
			
		||||
      ((start + 240 - text.length) ? '...' : '');
 | 
			
		||||
    var rv = $('<p class="context"></p>').text(excerpt);
 | 
			
		||||
    $.each(hlwords, function() {
 | 
			
		||||
      rv = rv.highlightText(this, 'highlighted');
 | 
			
		||||
    });
 | 
			
		||||
    return rv;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
$(document).ready(function() {
 | 
			
		||||
  Search.init();
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										648
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/api.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,648 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>API — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" />
 | 
			
		||||
    <link rel="prev" title="Extensions" href="extensions.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul class="current">
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">API</a><ul>
 | 
			
		||||
<li class="toctree-l2"><a class="reference internal" href="#pose-wrangler-v2-main">pose_wrangler.v2.main</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>API</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
            <a href="_sources/api.rst.txt" rel="nofollow"> View page source</a>
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <section id="api">
 | 
			
		||||
<h1>API<a class="headerlink" href="#api" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<section id="pose-wrangler-v2-main">
 | 
			
		||||
<h2>pose_wrangler.v2.main<a class="headerlink" href="#pose-wrangler-v2-main" title="Permalink to this headline"></a></h2>
 | 
			
		||||
<dl class="py class">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI">
 | 
			
		||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pose_wrangler.v2.main.</span></span><span class="sig-name descname"><span class="pre">UERBFAPI</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">view</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parent</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">file_path</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">pose_wrangler.model.api.RBFAPI</span></code></p>
 | 
			
		||||
<p>Main entry point for interacting with the UERBFSolverNode and UEPoseBlenderNode</p>
 | 
			
		||||
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">pose_wrangler.v2</span> <span class="kn">import</span> <span class="n">main</span>
 | 
			
		||||
<span class="gp">>>> </span><span class="n">rbf_api</span> <span class="o">=</span> <span class="n">main</span><span class="o">.</span><span class="n">UERBFAPI</span><span class="p">(</span><span class="n">view</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
 | 
			
		||||
<span class="gp">>>> </span><span class="n">rbf_api</span><span class="o">.</span><span class="n">create_rbf_solver</span><span class="p">(</span><span class="n">solver_name</span><span class="o">=</span><span class="s2">"ExampleSolver"</span><span class="p">,</span> <span class="n">drivers</span><span class="o">=</span><span class="p">[</span><span class="s1">'leg_l'</span><span class="p">])</span>
 | 
			
		||||
</pre></div>
 | 
			
		||||
</div>
 | 
			
		||||
<dl class="py attribute">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.VERSION">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">VERSION</span></span><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">'2.0.0'</span></em><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.VERSION" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd></dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.extensions">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">extensions</span></span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.extensions" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>list of pose wrangler extensions currently loaded</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>list[<a class="reference internal" href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension" title="pose_wrangler.v2.model.base_extension.PoseWranglerExtension">pose_wrangler.v2.model.base_extension.PoseWranglerExtension</a>]</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.view">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">view</span></span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.view" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>reference to the ui QWidget</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>QtWidgets.QWidget or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.current_solver">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">current_solver</span></span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.current_solver" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>reference to the current solver</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>api.RBFNode or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.mirror_mapping">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">mirror_mapping</span></span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.mirror_mapping" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>reference to the currently loaded mirror mapping</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>mirror_mapping.MirrorMapping object</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.rbf_solvers">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">rbf_solvers</span></span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.rbf_solvers" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>list of rbf solvers in the scene</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>list</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.create_rbf_solver">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">create_rbf_solver</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">solver_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">drivers</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.create_rbf_solver" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Create an rbf solver node with the given name and the specified driver transforms</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>solver_name</strong> (<em>str</em>) – name of the solver node</p></li>
 | 
			
		||||
<li><p><strong>drivers</strong> (<em>list</em>) – list of driver transform node names</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>RBFNode ref</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>api.RBFNode</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.delete_rbf_solver">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">delete_rbf_solver</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.delete_rbf_solver" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Delete the specified solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.edit_solver">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">edit_solver</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">edit</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.edit_solver" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Edit or finish editing the specified solver. Enables pose creation/driven node changes via the ui</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>edit</strong> (<em>bool</em>) – set edit mode on or off</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.mirror_rbf_solver">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">mirror_rbf_solver</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.mirror_rbf_solver" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Mirror the current solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>mirrored solver reference</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>api.RBFNode</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.get_rbf_solver_by_name">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">get_rbf_solver_by_name</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">solver_name</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.get_rbf_solver_by_name" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Searches the scene for an rbf solver with the given name. Case insensitive</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>solver_name</strong> (<em>str</em>) – Solver node name</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>found node or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>api.RBFNode or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.add_drivers">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">add_drivers</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">drivers</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.add_drivers" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Add the specified drivers to the specified solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>drivers</strong> (<em>list</em>) – list of transform nodes</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.remove_drivers">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">remove_drivers</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">drivers</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.remove_drivers" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Remove the specified drivers from the specified solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>drivers</strong> (<em>list</em>) – list of driver transform nodes</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.add_driven_transforms">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">add_driven_transforms</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">driven_nodes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">edit</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.add_driven_transforms" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Add driven transforms to the specified solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>driven_nodes</strong> (<em>list</em>) – list of transform nodes</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
<li><p><strong>edit</strong> (<em>bool</em>) – should this transform not be connected to the pose blender output upon creation</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.remove_driven">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">remove_driven</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">driven_nodes</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.remove_driven" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Remove driven transforms from the specified solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>driven_nodes</strong> (<em>list</em>) – list of transform nodes</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.add_blendshape">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">add_blendshape</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">mesh_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">base_mesh</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.add_blendshape" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Add an existing blendshape for the current pose</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose the blendshape is associated with</p></li>
 | 
			
		||||
<li><p><strong>mesh_name</strong> (<em>str</em>) – name of the existing blendshape mesh</p></li>
 | 
			
		||||
<li><p><strong>base_mesh</strong> (<em>str</em>) – name of the mesh the blendshape mesh is derived from</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.create_blendshape">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">create_blendshape</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">mesh_name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">edit</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.create_blendshape" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Create a new blendshape for the given pose and mesh</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose to create this blendshape for</p></li>
 | 
			
		||||
<li><p><strong>mesh_name</strong> (<em>str</em>) – name of the mesh to create the blendshape from</p></li>
 | 
			
		||||
<li><p><strong>edit</strong> (<em>bool</em>) – should this blendshape be edited straight away</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>name of the newly created blendshape mesh</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>str</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.delete_blendshape">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">delete_blendshape</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.delete_blendshape" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Delete the blendshape associated with the specified pose</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose to delete blendshapes for</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.edit_blendshape">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">edit_blendshape</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">edit</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.edit_blendshape" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Edit or finish editing the blendshape associated with the specified pose name</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose the blendshape is associated with</p></li>
 | 
			
		||||
<li><p><strong>edit</strong> (<em>bool</em>) – True = enable editing, False =  finish editing</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.isolate_blendshape">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">isolate_blendshape</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">isolate</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.isolate_blendshape" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Isolate the blendshape associated with the specified pose name, disabling all other blendshapes.</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose the blendshape is associated with</p></li>
 | 
			
		||||
<li><p><strong>isolate</strong> (<em>bool</em>) – True = isolate the blendshape, False = reconnect all disconnected blendshapes</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.create_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">create_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.create_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Create a new pose for the specified solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the new pose</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.delete_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">delete_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.delete_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Remove a pose from the given solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose to remove</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.go_to_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">go_to_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.go_to_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Move the driver/driven transforms to the given pose</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.mirror_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">mirror_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.mirror_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Mirror a pose to the mirror of the current solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.mute_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">mute_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">mute</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.mute_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Mute or unmute the specified pose, removing all influences of the pose from the solver.
 | 
			
		||||
NOTE: This will affect the solver radius if automatic radius is enabled.</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose</p></li>
 | 
			
		||||
<li><p><strong>mute</strong> (<em>bool</em>) – mute or unmute the pose</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.rename_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">rename_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">new_pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.rename_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Rename a pose on the given solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose</p></li>
 | 
			
		||||
<li><p><strong>new_pose_name</strong> (<em>str</em>) – new name of the pose</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.update_pose">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">update_pose</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pose_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.update_pose" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Update the pose for the given solver</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>pose_name</strong> (<em>str</em>) – name of the pose to update</p></li>
 | 
			
		||||
<li><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.deserialize_from_file">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">deserialize_from_file</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">file_path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver_names</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.deserialize_from_file" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Deserialize solvers from a specific file.</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>file_path</strong> (<em>str</em>) – json file to load</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.serialize_to_file">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">serialize_to_file</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">file_path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solvers</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.serialize_to_file" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Serialize the specified solvers to a file</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>file_path</strong> (<em>str</em>) – json file to serialize</p></li>
 | 
			
		||||
<li><p><strong>solvers</strong> (<em>list</em>) – list of api.RBFNode to serialize</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.deserialize">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">deserialize</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">solver_names</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.deserialize" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Deserialize and load the solvers from the data specified</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><ul class="simple">
 | 
			
		||||
<li><p><strong>data</strong> (<em>dict</em>) – serialized solver data</p></li>
 | 
			
		||||
<li><p><strong>solver_names</strong> (<em>list</em><em>, </em><em>optional</em>) – list of solver names to load from the data</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.serialize">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">serialize</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">solvers</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.serialize" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Serialize the specified solvers</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>solvers</strong> (<em>list</em>) – list of api.RBFNode to serialize</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>serialized solver data</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>dict</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.load">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">load</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.load" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Load the default pose wrangler settings</p>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.get_context">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">get_context</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.get_context" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Get the current solver context</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>pose wrangler context containing the current solver and all rbf solvers</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>context.PoseWranglerContext</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.get_ui_context">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">get_ui_context</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.get_ui_context" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>If the ui is available, return the ui context</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>ui context containing the current state of the ui</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>ui_context.PoseWranglerUIContext or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.get_extension_by_type">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">get_extension_by_type</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">class_ref</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.get_extension_by_type" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Get a reference to one of the loaded extensions from a class type</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>class_ref</strong> (<a class="reference internal" href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension" title="pose_wrangler.v2.model.base_extension.PoseWranglerExtension"><em>base_extension.PoseWranglerExtension</em></a>) – reference to an extension class</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>reference to a loaded extension if one is loaded</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>base_extension.PoseWranglerExtension instance or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.set_mirror_mapping">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">set_mirror_mapping</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.set_mirror_mapping" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Set the mirror mapping from a file</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>path</strong> (<em>str</em>) – path to json mirror mapping file</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.main.UERBFAPI.get_solver_edit_status">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">get_solver_edit_status</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">solver</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.main.UERBFAPI.get_solver_edit_status" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Check if the current solver is in ‘Edit’ mode</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>solver</strong> (<em>api.RBFNode</em>) – solver reference</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Returns</dt>
 | 
			
		||||
<dd class="field-even"><p>True = in edit mode, False = not in edit mode</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-odd">Return type</dt>
 | 
			
		||||
<dd class="field-odd"><p>bool</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
</section>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
 | 
			
		||||
        <a href="extensions.html" class="btn btn-neutral float-left" title="Extensions" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -0,0 +1,176 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>Extensions — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" />
 | 
			
		||||
    <link rel="next" title="API" href="api.html" />
 | 
			
		||||
    <link rel="prev" title="Mirror Mapping" href="mirror_mapping.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul class="current">
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>Extensions</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
            <a href="_sources/extensions.rst.txt" rel="nofollow"> View page source</a>
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <section id="extensions">
 | 
			
		||||
<h1>Extensions<a class="headerlink" href="#extensions" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<p>You can now create custom extensions for PoseWrangler so you can introduce new features without having to edit the
 | 
			
		||||
core code base.</p>
 | 
			
		||||
<p>Custom extensions can be created by inheriting from the following class:</p>
 | 
			
		||||
<dl class="py class">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.model.base_extension.PoseWranglerExtension">
 | 
			
		||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pose_wrangler.v2.model.base_extension.</span></span><span class="sig-name descname"><span class="pre">PoseWranglerExtension</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">display_view</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">api</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.model.base_extension.PoseWranglerExtension" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
 | 
			
		||||
<p>Base class for extending pose wrangler with custom utilities that can be dynamically added to the UI</p>
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.model.base_extension.PoseWranglerExtension.api">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">api</span></span><a class="headerlink" href="#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.api" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Get the current API</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>Reference to the main API interface</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p><a class="reference internal" href="api.html#pose_wrangler.v2.main.UERBFAPI" title="pose_wrangler.v2.main.UERBFAPI">pose_wrangler.v2.main.UERBFAPI</a></p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py property">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.model.base_extension.PoseWranglerExtension.view">
 | 
			
		||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">view</span></span><a class="headerlink" href="#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.view" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Get the current view widget. This should be overridden by custom extensions if you wish to embed a UI for this
 | 
			
		||||
extension into the main PoseWrangler UI</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Returns</dt>
 | 
			
		||||
<dd class="field-odd"><p>Reference to the PySide widget associated with this extension</p>
 | 
			
		||||
</dd>
 | 
			
		||||
<dt class="field-even">Return type</dt>
 | 
			
		||||
<dd class="field-even"><p>QWidget or None</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.model.base_extension.PoseWranglerExtension.execute">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">execute</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.execute" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Generic entrypoint for executing the extension</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Param</dt>
 | 
			
		||||
<dd class="field-odd"><p>context: pose wrangler context containing current solver and all solvers</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<dl class="py method">
 | 
			
		||||
<dt class="sig sig-object py" id="pose_wrangler.v2.model.base_extension.PoseWranglerExtension.on_context_changed">
 | 
			
		||||
<span class="sig-name descname"><span class="pre">on_context_changed</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">new_context</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.on_context_changed" title="Permalink to this definition"></a></dt>
 | 
			
		||||
<dd><p>Context event called when the current solver is set via the API</p>
 | 
			
		||||
<dl class="field-list simple">
 | 
			
		||||
<dt class="field-odd">Parameters</dt>
 | 
			
		||||
<dd class="field-odd"><p><strong>new_context</strong> (<em>pose_wrangler.v2.model.context.PoseWranglerContext</em><em> or </em><em>None</em>) – pose wrangler context containing current solver and all solvers</p>
 | 
			
		||||
</dd>
 | 
			
		||||
</dl>
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
</dd></dl>
 | 
			
		||||
 | 
			
		||||
<p>When PoseWrangler loads up, it will automatically detect and load any classes that inherit from <code class="docutils literal notranslate"><span class="pre">PoseWranglerExtension</span></code>
 | 
			
		||||
on startup.</p>
 | 
			
		||||
<div class="admonition note">
 | 
			
		||||
<p class="admonition-title">Note</p>
 | 
			
		||||
<p>To make sure that your extension loads, please make sure that it is imported before you start PoseWrangler.</p>
 | 
			
		||||
</div>
 | 
			
		||||
<p>Example extensions can be found under <code class="docutils literal notranslate"><span class="pre">pose_wrangler.v2.extensions</span></code></p>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
 | 
			
		||||
        <a href="mirror_mapping.html" class="btn btn-neutral float-left" title="Mirror Mapping" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
 | 
			
		||||
        <a href="api.html" class="btn btn-neutral float-right" title="API" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -0,0 +1,310 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" />
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>Index — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="#" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>Index</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
 | 
			
		||||
<h1 id="index">Index</h1>
 | 
			
		||||
 | 
			
		||||
<div class="genindex-jumpbox">
 | 
			
		||||
 <a href="#A"><strong>A</strong></a>
 | 
			
		||||
 | <a href="#C"><strong>C</strong></a>
 | 
			
		||||
 | <a href="#D"><strong>D</strong></a>
 | 
			
		||||
 | <a href="#E"><strong>E</strong></a>
 | 
			
		||||
 | <a href="#G"><strong>G</strong></a>
 | 
			
		||||
 | <a href="#I"><strong>I</strong></a>
 | 
			
		||||
 | <a href="#L"><strong>L</strong></a>
 | 
			
		||||
 | <a href="#M"><strong>M</strong></a>
 | 
			
		||||
 | <a href="#O"><strong>O</strong></a>
 | 
			
		||||
 | <a href="#P"><strong>P</strong></a>
 | 
			
		||||
 | <a href="#R"><strong>R</strong></a>
 | 
			
		||||
 | <a href="#S"><strong>S</strong></a>
 | 
			
		||||
 | <a href="#U"><strong>U</strong></a>
 | 
			
		||||
 | <a href="#V"><strong>V</strong></a>
 | 
			
		||||
 
 | 
			
		||||
</div>
 | 
			
		||||
<h2 id="A">A</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.add_blendshape">add_blendshape() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.add_driven_transforms">add_driven_transforms() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.add_drivers">add_drivers() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.api">api (pose_wrangler.v2.model.base_extension.PoseWranglerExtension property)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="C">C</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.create_blendshape">create_blendshape() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.create_pose">create_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.create_rbf_solver">create_rbf_solver() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.current_solver">current_solver (pose_wrangler.v2.main.UERBFAPI property)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="D">D</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.delete_blendshape">delete_blendshape() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.delete_pose">delete_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.delete_rbf_solver">delete_rbf_solver() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.deserialize">deserialize() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.deserialize_from_file">deserialize_from_file() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="E">E</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.edit_blendshape">edit_blendshape() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.edit_solver">edit_solver() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.execute">execute() (pose_wrangler.v2.model.base_extension.PoseWranglerExtension method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.extensions">extensions (pose_wrangler.v2.main.UERBFAPI property)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="G">G</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.get_context">get_context() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.get_extension_by_type">get_extension_by_type() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.get_rbf_solver_by_name">get_rbf_solver_by_name() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.get_solver_edit_status">get_solver_edit_status() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.get_ui_context">get_ui_context() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.go_to_pose">go_to_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="I">I</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.isolate_blendshape">isolate_blendshape() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="L">L</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.load">load() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="M">M</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.mirror_mapping">mirror_mapping (pose_wrangler.v2.main.UERBFAPI property)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.mirror_pose">mirror_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.mirror_rbf_solver">mirror_rbf_solver() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.mute_pose">mute_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="O">O</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.on_context_changed">on_context_changed() (pose_wrangler.v2.model.base_extension.PoseWranglerExtension method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="P">P</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension">PoseWranglerExtension (class in pose_wrangler.v2.model.base_extension)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="R">R</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.rbf_solvers">rbf_solvers (pose_wrangler.v2.main.UERBFAPI property)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.remove_driven">remove_driven() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.remove_drivers">remove_drivers() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.rename_pose">rename_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="S">S</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.serialize">serialize() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.serialize_to_file">serialize_to_file() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.set_mirror_mapping">set_mirror_mapping() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="U">U</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI">UERBFAPI (class in pose_wrangler.v2.main)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.update_pose">update_pose() (pose_wrangler.v2.main.UERBFAPI method)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
<h2 id="V">V</h2>
 | 
			
		||||
<table style="width: 100%" class="indextable genindextable"><tr>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.VERSION">VERSION (pose_wrangler.v2.main.UERBFAPI attribute)</a>
 | 
			
		||||
</li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
  <td style="width: 33%; vertical-align: top;"><ul>
 | 
			
		||||
      <li><a href="api.html#pose_wrangler.v2.main.UERBFAPI.view">view (pose_wrangler.v2.main.UERBFAPI property)</a>
 | 
			
		||||
 | 
			
		||||
      <ul>
 | 
			
		||||
        <li><a href="extensions.html#pose_wrangler.v2.model.base_extension.PoseWranglerExtension.view">(pose_wrangler.v2.model.base_extension.PoseWranglerExtension property)</a>
 | 
			
		||||
</li>
 | 
			
		||||
      </ul></li>
 | 
			
		||||
  </ul></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										168
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,168 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>Pose Wrangler Documentation — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" />
 | 
			
		||||
    <link rel="next" title="2.0.0 Overview" href="overview.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="#" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="#">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="#" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>Pose Wrangler Documentation</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
            <a href="_sources/index.rst.txt" rel="nofollow"> View page source</a>
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <section id="pose-wrangler-documentation">
 | 
			
		||||
<h1>Pose Wrangler Documentation<a class="headerlink" href="#pose-wrangler-documentation" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<div class="toctree-wrapper compound">
 | 
			
		||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a><ul>
 | 
			
		||||
<li class="toctree-l2"><a class="reference internal" href="overview.html#ui-overview">UI Overview</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a><ul>
 | 
			
		||||
<li class="toctree-l2"><a class="reference internal" href="api.html#pose-wrangler-v2-main">pose_wrangler.v2.main</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</li>
 | 
			
		||||
</ul>
 | 
			
		||||
</div>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="overview">
 | 
			
		||||
<h1>Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<p>PoseWrangler is a tool for interfacing with Epic’s MayaUERBFPlugin. The plugin is distributed by Epic Games and installed via Quixel Bridge.</p>
 | 
			
		||||
<section id="versions">
 | 
			
		||||
<h2>Versions<a class="headerlink" href="#versions" title="Permalink to this headline"></a></h2>
 | 
			
		||||
<section id="id1">
 | 
			
		||||
<h3>1.0.0:<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<ul class="simple">
 | 
			
		||||
<li><p>Supports legacy scenes created with the UE4RBFSolverNode</p></li>
 | 
			
		||||
<li><p>Supports Maya 2018-2022</p></li>
 | 
			
		||||
<li><p>Provides upgrade workflow to migrate to V2</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="id2">
 | 
			
		||||
<h3>2.0.0:<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<ul class="simple">
 | 
			
		||||
<li><p>Supports scenes created with the UERBFSolverNode</p></li>
 | 
			
		||||
<li><p>Multiple Driver Support</p></li>
 | 
			
		||||
<li><p>Initial blendshape support (WIP)</p></li>
 | 
			
		||||
<li><p>Supports Maya 2018-2022</p></li>
 | 
			
		||||
<li><p>Support for custom mirror mappings to allow for rigs with naming conventions that deviate from the default UE5 conventions</p></li>
 | 
			
		||||
<li><p>Fully automatable via Python and MayaPy</p></li>
 | 
			
		||||
<li><p>Serialization/deserialization to dictionary or JSON file</p></li>
 | 
			
		||||
<li><p>Support for custom extensions and context menu actions</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</section>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="contributors">
 | 
			
		||||
<h2>Contributors<a class="headerlink" href="#contributors" title="Permalink to this headline"></a></h2>
 | 
			
		||||
<ul class="simple">
 | 
			
		||||
<li><p>Chris Evans</p></li>
 | 
			
		||||
<li><p>Judd Simantov</p></li>
 | 
			
		||||
<li><p>David Corral</p></li>
 | 
			
		||||
<li><p>Borna Berc</p></li>
 | 
			
		||||
<li><p>Chris Theodosius</p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</section>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="indices-and-tables">
 | 
			
		||||
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<ul class="simple">
 | 
			
		||||
<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
 | 
			
		||||
<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
 | 
			
		||||
<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
 | 
			
		||||
        <a href="overview.html" class="btn btn-neutral float-right" title="2.0.0 Overview" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -0,0 +1,168 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>Mirror Mapping — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" />
 | 
			
		||||
    <link rel="next" title="Extensions" href="extensions.html" />
 | 
			
		||||
    <link rel="prev" title="Upgrading to 2.0.0" href="upgrading.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul class="current">
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>Mirror Mapping</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
            <a href="_sources/mirror_mapping.rst.txt" rel="nofollow"> View page source</a>
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <section id="mirror-mapping">
 | 
			
		||||
<h1>Mirror Mapping<a class="headerlink" href="#mirror-mapping" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<p>Mirror mapping enables Pose Wrangler to support custom skeletons when mirroring RBF solvers and poses.</p>
 | 
			
		||||
<p>Below is the mirror mapping for characters following the MetaHuman naming conventions:</p>
 | 
			
		||||
<blockquote>
 | 
			
		||||
<div><div class="highlight-JSON notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="w"></span>
 | 
			
		||||
<span class="w">    </span><span class="nt">"solver_expression"</span><span class="p">:</span><span class="w"> </span><span class="s2">"(?P<prefix>[a-zA-Z0-9]+)?(?P<side>_[lr]{1}_)(?P<suffix>[a-zA-Z0-9_]+)"</span><span class="p">,</span><span class="w"></span>
 | 
			
		||||
<span class="w">    </span><span class="nt">"transform_expression"</span><span class="p">:</span><span class="w"> </span><span class="s2">"(?P<prefix>[a-zA-Z0-9_]+)?(?P<side>_[lr]{1}_)(?P<suffix>[a-zA-Z0-9_]+)"</span><span class="p">,</span><span class="w"></span>
 | 
			
		||||
<span class="w">    </span><span class="nt">"left"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
 | 
			
		||||
<span class="w">        </span><span class="nt">"solver_syntax"</span><span class="p">:</span><span class="w"> </span><span class="s2">"_l_"</span><span class="p">,</span><span class="w"></span>
 | 
			
		||||
<span class="w">        </span><span class="nt">"transform_syntax"</span><span class="p">:</span><span class="w"> </span><span class="s2">"_l_"</span><span class="w"></span>
 | 
			
		||||
<span class="w">        </span><span class="p">},</span><span class="w"></span>
 | 
			
		||||
<span class="w">    </span><span class="nt">"right"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
 | 
			
		||||
<span class="w">        </span><span class="nt">"solver_syntax"</span><span class="p">:</span><span class="w"> </span><span class="s2">"_r_"</span><span class="p">,</span><span class="w"></span>
 | 
			
		||||
<span class="w">        </span><span class="nt">"transform_syntax"</span><span class="p">:</span><span class="w"> </span><span class="s2">"_r_"</span><span class="w"></span>
 | 
			
		||||
<span class="w">    </span><span class="p">}</span><span class="w"></span>
 | 
			
		||||
<span class="p">}</span><span class="w"></span>
 | 
			
		||||
</pre></div>
 | 
			
		||||
</div>
 | 
			
		||||
</div></blockquote>
 | 
			
		||||
<table class="colwidths-given docutils align-default" id="id1">
 | 
			
		||||
<caption><span class="caption-text">Title</span><a class="headerlink" href="#id1" title="Permalink to this table"></a></caption>
 | 
			
		||||
<colgroup>
 | 
			
		||||
<col style="width: 33%" />
 | 
			
		||||
<col style="width: 67%" />
 | 
			
		||||
</colgroup>
 | 
			
		||||
<thead>
 | 
			
		||||
<tr class="row-odd"><th class="head"><p>Key</p></th>
 | 
			
		||||
<th class="head"><p>Definition</p></th>
 | 
			
		||||
</tr>
 | 
			
		||||
</thead>
 | 
			
		||||
<tbody>
 | 
			
		||||
<tr class="row-even"><td><p>solver_expression</p></td>
 | 
			
		||||
<td><p>A regular expression used to match against the solver node name</p></td>
 | 
			
		||||
</tr>
 | 
			
		||||
<tr class="row-odd"><td><p>transform_expression</p></td>
 | 
			
		||||
<td><p>A regular expression used to match against the transform (joint) node name</p></td>
 | 
			
		||||
</tr>
 | 
			
		||||
<tr class="row-even"><td><p>left</p></td>
 | 
			
		||||
<td><p>dictionary containing the expected match for the solver_expression and <br> transform_expression</p></td>
 | 
			
		||||
</tr>
 | 
			
		||||
<tr class="row-odd"><td><p>right</p></td>
 | 
			
		||||
<td><p>dictionary containing the expected match for the solver_expression and <br> transform_expression</p></td>
 | 
			
		||||
</tr>
 | 
			
		||||
</tbody>
 | 
			
		||||
</table>
 | 
			
		||||
<div class="admonition note">
 | 
			
		||||
<p class="admonition-title">Note</p>
 | 
			
		||||
<p>As an example if we wanted to mirror a solver called <code class="docutils literal notranslate"><span class="pre">calf_l_UERBFSolver</span></code> we first try to match the name
 | 
			
		||||
of the solver against the <code class="docutils literal notranslate"><span class="pre">solver_expression</span></code>. If the match fails, you’ll see an error appear in the output
 | 
			
		||||
log that the solver name doesn’t match the settings defined in mirror mapping.</p>
 | 
			
		||||
<p>If the match succeeds, it will then iterate through the groups in the matchdict to determine if one of the groups
 | 
			
		||||
matches the <code class="docutils literal notranslate"><span class="pre">solver_syntax</span></code> for the left hand side. If it does, it will replace it with the right and vice versa.</p>
 | 
			
		||||
<p>In this case, we will end up with a matchdict that looks something like this: <br>
 | 
			
		||||
<code class="docutils literal notranslate"><span class="pre">{"prefix":</span> <span class="pre">"calf",</span> <span class="pre">"side":</span> <span class="pre">"_l_",</span> <span class="pre">"suffix":</span> <span class="pre">"UERBFSolver"}</span></code> <br>
 | 
			
		||||
The mapping will iterate through this dictionary and attempt to match each value against the <code class="docutils literal notranslate"><span class="pre">solver_syntax</span></code> of
 | 
			
		||||
the <code class="docutils literal notranslate"><span class="pre">left</span></code> and <code class="docutils literal notranslate"><span class="pre">right</span></code> group defined in mirror mapping. If it matches the <code class="docutils literal notranslate"><span class="pre">left</span></code> group it will replace the
 | 
			
		||||
<code class="docutils literal notranslate"><span class="pre">side</span></code> value with the <code class="docutils literal notranslate"><span class="pre">solver_syntax</span></code> specified in the <code class="docutils literal notranslate"><span class="pre">right</span></code> group resulting in the following dictionary: <br>
 | 
			
		||||
<code class="docutils literal notranslate"><span class="pre">{"prefix":</span> <span class="pre">"calf",</span> <span class="pre">"side":</span> <span class="pre">"_r_",</span> <span class="pre">"suffix":</span> <span class="pre">"UERBFSolver"}</span></code> <br></p>
 | 
			
		||||
<p>The same thing then happens for the drivers and driven transforms associated with the solver, using <code class="docutils literal notranslate"><span class="pre">transform_expression</span></code>
 | 
			
		||||
and <code class="docutils literal notranslate"><span class="pre">transform_syntax</span></code> in place of the solver.</p>
 | 
			
		||||
</div>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
 | 
			
		||||
        <a href="upgrading.html" class="btn btn-neutral float-left" title="Upgrading to 2.0.0" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
 | 
			
		||||
        <a href="extensions.html" class="btn btn-neutral float-right" title="Extensions" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
# Sphinx inventory version 2
 | 
			
		||||
# Project: Pose Wrangler
 | 
			
		||||
# Version: 
 | 
			
		||||
# The remainder of this file is compressed using zlib.
 | 
			
		||||
xڵ<EFBFBD>Mo<EFBFBD>0<0C><><EFBFBD><02>k<EFBFBD><6B><EFBFBD><EFBFBD>6,rh<1B><>vd<><64><05><0B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22>v<EFBFBD>`C,<2C>fP<66>C<EFBFBD>5EI+<0B><><10>p0<70><30><EFBFBD><14><><EFBFBD>}<7D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><11><><EFBFBD>	<09><><0E>
 | 
			
		||||
<EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD><EFBFBD>s<C289>U<EFBFBD><55><11>R\q<>ԶDC 	p<><70>30=H켓<48>)#l><3E><>g<EFBFBD><06><>%<25><>H<EFBFBD>+<2B>a<EFBFBD><1D><><EFBFBD><EFBFBD><EFBFBD>'uƀt<13>6J<36>q<EFBFBD><71> 
 | 
			
		||||
<1C>(<28><>J<><04>`<60>0<EFBFBD><30>/X<><58>wF	<09>c|>
 | 
			
		||||
@@ -0,0 +1,177 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>2.0.0 Overview — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" />
 | 
			
		||||
    <link rel="next" title="Upgrading to 2.0.0" href="upgrading.html" />
 | 
			
		||||
    <link rel="prev" title="Pose Wrangler Documentation" href="index.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul class="current">
 | 
			
		||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">2.0.0 Overview</a><ul>
 | 
			
		||||
<li class="toctree-l2"><a class="reference internal" href="#ui-overview">UI Overview</a><ul>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#solver-view">1) Solver View</a></li>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#pose-view">2) Pose View</a></li>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#driver-view">3) Driver View</a></li>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#driven-transforms-blendshape-view">4) Driven Transforms / Blendshape View</a></li>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#extensions-and-settings-view">5) Extensions and Settings View</a></li>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#top-menu">6) Top Menu</a></li>
 | 
			
		||||
<li class="toctree-l3"><a class="reference internal" href="#output-log">7) Output Log</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
</li>
 | 
			
		||||
</ul>
 | 
			
		||||
</li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>2.0.0 Overview</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
            <a href="_sources/overview.rst.txt" rel="nofollow"> View page source</a>
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <section id="overview">
 | 
			
		||||
<h1>2.0.0 Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<p>Version 2.0.0 is a refactor of the original Pose Wrangler. The goal of this version has been to separate the UI
 | 
			
		||||
logic from the backend, enabling users to automate RBF setup via Python and create custom extensions to add new
 | 
			
		||||
functionality.</p>
 | 
			
		||||
<section id="ui-overview">
 | 
			
		||||
<h2>UI Overview<a class="headerlink" href="#ui-overview" title="Permalink to this headline"></a></h2>
 | 
			
		||||
<a class="reference internal image-reference" href="_images/overview.png"><img alt="UI Overview" src="_images/overview.png" style="width: 800px;" /></a>
 | 
			
		||||
<section id="solver-view">
 | 
			
		||||
<h3>1) Solver View<a class="headerlink" href="#solver-view" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>Here is where you can find a list of all the RBF solvers currently available in the scene and can edit, create, delete
 | 
			
		||||
or mirror solvers.</p>
 | 
			
		||||
<p>In order to make changes to the poses, drivers or driven transforms/blendshapes you need to toggle a solver into <cite>edit</cite>
 | 
			
		||||
mode via the <cite>Edit Selected Solver</cite> button.</p>
 | 
			
		||||
<div class="admonition note">
 | 
			
		||||
<p class="admonition-title">Note</p>
 | 
			
		||||
<p>Only one solver can be edited at a single time.</p>
 | 
			
		||||
</div>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="pose-view">
 | 
			
		||||
<h3>2) Pose View<a class="headerlink" href="#pose-view" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>Here you can find a list of all the poses. In order to make any changes to the poses, you need to edit the corresponding solver.</p>
 | 
			
		||||
<div class="admonition warning">
 | 
			
		||||
<p class="admonition-title">Warning</p>
 | 
			
		||||
<p>Most of these are self-explanatory, but is it worth noting that <cite>Mute Pose</cite> will enable and disable the pose on the
 | 
			
		||||
solver via the <cite>targetEnable</cite> attribute. This means that if the RBF solver node is set to use <cite>automatic radius</cite>
 | 
			
		||||
then the radius will be calculated without the influence of the muted poses.</p>
 | 
			
		||||
</div>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="driver-view">
 | 
			
		||||
<h3>3) Driver View<a class="headerlink" href="#driver-view" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>2.0.0 supports multiple drivers. Here you can add/remove driver transforms.</p>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="driven-transforms-blendshape-view">
 | 
			
		||||
<h3>4) Driven Transforms / Blendshape View<a class="headerlink" href="#driven-transforms-blendshape-view" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>Here you can add/remove driven transforms and create/add blendshapes.</p>
 | 
			
		||||
<div class="admonition note">
 | 
			
		||||
<p class="admonition-title">Note</p>
 | 
			
		||||
<p>The blendshape workflow is currently a work in progress and may change in the future.</p>
 | 
			
		||||
</div>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="extensions-and-settings-view">
 | 
			
		||||
<h3>5) Extensions and Settings View<a class="headerlink" href="#extensions-and-settings-view" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>Pose Wrangler now supports writing custom extensions for the tool that can be embedded into the UI here.
 | 
			
		||||
<cite>Core Extensions</cite> are default extensions that ship with Pose Wrangler. <cite>Pose Exporter</cite> is an example of a custom
 | 
			
		||||
extension used by the MetaHuman team. For more information on how these extensions work and how to create your own,
 | 
			
		||||
please refer to the <a class="reference internal" href="extensions.html"><span class="doc">Extensions</span></a> page.</p>
 | 
			
		||||
<p>You can also change the mirror mapping, which will allow you to specify a custom mapping if your skeleton does not
 | 
			
		||||
match the default MetaHuman skeleton and the mirror solver/pose functionality is causing unexpected results.</p>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="top-menu">
 | 
			
		||||
<h3>6) Top Menu<a class="headerlink" href="#top-menu" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>Here you can import/export RBF solvers to/from a JSON file, change the theme and view the help.</p>
 | 
			
		||||
</section>
 | 
			
		||||
<section id="output-log">
 | 
			
		||||
<h3>7) Output Log<a class="headerlink" href="#output-log" title="Permalink to this headline"></a></h3>
 | 
			
		||||
<p>Displays debug, info, warning and error messages.</p>
 | 
			
		||||
</section>
 | 
			
		||||
</section>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
 | 
			
		||||
        <a href="index.html" class="btn btn-neutral float-left" title="Pose Wrangler Documentation" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
 | 
			
		||||
        <a href="upgrading.html" class="btn btn-neutral float-right" title="Upgrading to 2.0.0" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										119
									
								
								Scripts/Animation/epic_pose_wrangler/docs/site/html/search.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,119 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" />
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>Search — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
    
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <script src="_static/searchtools.js"></script>
 | 
			
		||||
    <script src="_static/language_data.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="#" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="#" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="upgrading.html">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>Search</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <noscript>
 | 
			
		||||
  <div id="fallback" class="admonition warning">
 | 
			
		||||
    <p class="last">
 | 
			
		||||
      Please activate JavaScript to enable the search functionality.
 | 
			
		||||
    </p>
 | 
			
		||||
  </div>
 | 
			
		||||
  </noscript>
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  <div id="search-results">
 | 
			
		||||
  
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script>
 | 
			
		||||
  <script>
 | 
			
		||||
    jQuery(function() { Search.loadIndex("searchindex.js"); });
 | 
			
		||||
  </script>
 | 
			
		||||
  
 | 
			
		||||
  <script id="searchindexloader"></script>
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -0,0 +1,117 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="writer-html5" lang="en" >
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
 | 
			
		||||
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
  <title>Upgrading to 2.0.0 — Pose Wrangler 2.0.0 documentation</title>
 | 
			
		||||
      <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
 | 
			
		||||
      <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 | 
			
		||||
  <!--[if lt IE 9]>
 | 
			
		||||
    <script src="_static/js/html5shiv.min.js"></script>
 | 
			
		||||
  <![endif]-->
 | 
			
		||||
  
 | 
			
		||||
        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
 | 
			
		||||
        <script src="_static/jquery.js"></script>
 | 
			
		||||
        <script src="_static/underscore.js"></script>
 | 
			
		||||
        <script src="_static/doctools.js"></script>
 | 
			
		||||
    <script src="_static/js/theme.js"></script>
 | 
			
		||||
    <link rel="index" title="Index" href="genindex.html" />
 | 
			
		||||
    <link rel="search" title="Search" href="search.html" />
 | 
			
		||||
    <link rel="next" title="Mirror Mapping" href="mirror_mapping.html" />
 | 
			
		||||
    <link rel="prev" title="2.0.0 Overview" href="overview.html" /> 
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body class="wy-body-for-nav"> 
 | 
			
		||||
  <div class="wy-grid-for-nav">
 | 
			
		||||
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
 | 
			
		||||
      <div class="wy-side-scroll">
 | 
			
		||||
        <div class="wy-side-nav-search" >
 | 
			
		||||
            <a href="index.html" class="icon icon-home"> Pose Wrangler
 | 
			
		||||
          </a>
 | 
			
		||||
<div role="search">
 | 
			
		||||
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
 | 
			
		||||
    <input type="text" name="q" placeholder="Search docs" />
 | 
			
		||||
    <input type="hidden" name="check_keywords" value="yes" />
 | 
			
		||||
    <input type="hidden" name="area" value="default" />
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
 | 
			
		||||
              <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
 | 
			
		||||
<ul class="current">
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">2.0.0 Overview</a></li>
 | 
			
		||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Upgrading to 2.0.0</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="mirror_mapping.html">Mirror Mapping</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="extensions.html">Extensions</a></li>
 | 
			
		||||
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
 | 
			
		||||
    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
 | 
			
		||||
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
 | 
			
		||||
          <a href="index.html">Pose Wrangler</a>
 | 
			
		||||
      </nav>
 | 
			
		||||
 | 
			
		||||
      <div class="wy-nav-content">
 | 
			
		||||
        <div class="rst-content">
 | 
			
		||||
          <div role="navigation" aria-label="Page navigation">
 | 
			
		||||
  <ul class="wy-breadcrumbs">
 | 
			
		||||
      <li><a href="index.html" class="icon icon-home"></a> »</li>
 | 
			
		||||
      <li>Upgrading to 2.0.0</li>
 | 
			
		||||
      <li class="wy-breadcrumbs-aside">
 | 
			
		||||
            <a href="_sources/upgrading.rst.txt" rel="nofollow"> View page source</a>
 | 
			
		||||
      </li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <hr/>
 | 
			
		||||
</div>
 | 
			
		||||
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
 | 
			
		||||
           <div itemprop="articleBody">
 | 
			
		||||
             
 | 
			
		||||
  <section id="upgrading-to-2-0-0">
 | 
			
		||||
<h1>Upgrading to 2.0.0<a class="headerlink" href="#upgrading-to-2-0-0" title="Permalink to this headline"></a></h1>
 | 
			
		||||
<p>When you load up Pose Wrangler with a scene that contains <cite>UE4RBFSolverNode</cite> you will be greeted with the new legacy
 | 
			
		||||
version of PoseWrangler. This version is almost identical with the version previously available via GitHub, with the
 | 
			
		||||
addition of the log window and the upgrade button.</p>
 | 
			
		||||
<p>If you have the new version of the plugin available you will be presented with an option to upgrade your scene at the
 | 
			
		||||
top of the Pose Wrangler window. Pressing this button will execute an upgrade script that will replace all the
 | 
			
		||||
<cite>UE4RBFSolverNode</cite> with <cite>UERBFSolverNode</cite> and clean up old/redundant nodes left lingering in the scene.</p>
 | 
			
		||||
<a class="reference internal image-reference" href="_images/upgrade.png"><img alt="UI Overview" src="_images/upgrade.png" style="width: 800px;" /></a>
 | 
			
		||||
<p>If the upgrade is successful you will be presented with the new tool window.</p>
 | 
			
		||||
<a class="reference internal image-reference" href="_images/v2.png"><img alt="UI Overview" src="_images/v2.png" style="width: 800px;" /></a>
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
 | 
			
		||||
        <a href="overview.html" class="btn btn-neutral float-left" title="2.0.0 Overview" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
 | 
			
		||||
        <a href="mirror_mapping.html" class="btn btn-neutral float-right" title="Mirror Mapping" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  <hr/>
 | 
			
		||||
 | 
			
		||||
  <div role="contentinfo">
 | 
			
		||||
    <p>© Copyright 2022, Epic Games.</p>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
 | 
			
		||||
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
 | 
			
		||||
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
</footer>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script>
 | 
			
		||||
      jQuery(function () {
 | 
			
		||||
          SphinxRtdTheme.Navigation.enable(true);
 | 
			
		||||
      });
 | 
			
		||||
  </script> 
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										7
									
								
								Scripts/Animation/epic_pose_wrangler/log.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
			
		||||
#  Copyright Epic Games, Inc. All Rights Reserved.
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
# Grab the pose wrangler log
 | 
			
		||||
LOG = logging.getLogger("EpicGames.PoseWrangler")
 | 
			
		||||
# Set the logging level
 | 
			
		||||
LOG.setLevel(logging.DEBUG)
 | 
			
		||||
							
								
								
									
										30
									
								
								Scripts/Animation/epic_pose_wrangler/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,30 @@
 | 
			
		||||
#  Copyright Epic Games, Inc. All Rights Reserved.
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from epic_pose_wrangler.log import LOG
 | 
			
		||||
from epic_pose_wrangler.model.plugin_manager import PluginManager
 | 
			
		||||
 | 
			
		||||
class PoseWrangler(object):
 | 
			
		||||
    """
 | 
			
		||||
    Main entrypoint for interacting with PoseWrangler. Will handle loading the correct version of the tool based on the
 | 
			
		||||
    available version of the plugin
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, view=True):
 | 
			
		||||
        # Get the current version of the tool
 | 
			
		||||
        self._api = PluginManager.get_pose_wrangler(view=view, parent=self)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def api(self):
 | 
			
		||||
        return self._api
 | 
			
		||||
 | 
			
		||||
    def upgrade(self, file_path=None, delete_file=False):
 | 
			
		||||
        """
 | 
			
		||||
        Restart pose_wrangler with the specified serialized solver data file
 | 
			
		||||
        :param file_path :type str: path to serialized json data
 | 
			
		||||
        :param delete_file :type bool: should the file be deleted once the upgrade has completed?
 | 
			
		||||
        """
 | 
			
		||||
        LOG.info("Rebooting PoseWrangler")
 | 
			
		||||
        self._api = PluginManager.get_pose_wrangler(view=self._api.view, parent=self, file_path=file_path)
 | 
			
		||||
        if delete_file:
 | 
			
		||||
            os.remove(file_path)
 | 
			
		||||
							
								
								
									
										13
									
								
								Scripts/Animation/epic_pose_wrangler/model/api.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,13 @@
 | 
			
		||||
#  Copyright Epic Games, Inc. All Rights Reserved.
 | 
			
		||||
class RBFAPI(object):
 | 
			
		||||
    """
 | 
			
		||||
    Base class for creating RBF API classes
 | 
			
		||||
    """
 | 
			
		||||
    UPGRADE_AVAILABLE = False
 | 
			
		||||
    VERSION = "0.0.0"
 | 
			
		||||
 | 
			
		||||
    def __init__(self, view=False, parent=None, file_path=None):
 | 
			
		||||
        super(RBFAPI, self).__init__()
 | 
			
		||||
        self._view = view
 | 
			
		||||
        self._parent = parent
 | 
			
		||||
        self._file_path = file_path
 | 
			
		||||
							
								
								
									
										37
									
								
								Scripts/Animation/epic_pose_wrangler/model/exceptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,37 @@
 | 
			
		||||
#  Copyright Epic Games, Inc. All Rights Reserved.
 | 
			
		||||
from epic_pose_wrangler.log import LOG
 | 
			
		||||
 | 
			
		||||
class PoseWranglerException(Exception):
 | 
			
		||||
    """
 | 
			
		||||
    Base Exception for PoseWrangler related errors
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, message):
 | 
			
		||||
        super(PoseWranglerException, self).__init__(message)
 | 
			
		||||
        # Log the message as an error
 | 
			
		||||
        LOG.error(message)
 | 
			
		||||
 | 
			
		||||
class InvalidPoseWranglerPlugin(PoseWranglerException, RuntimeError):
 | 
			
		||||
    """
 | 
			
		||||
    Exception raised when no valid plugins could be loaded
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
class PoseWranglerSettingsError(PoseWranglerException):
 | 
			
		||||
    """
 | 
			
		||||
    Raised when a setting is invalid
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
class InvalidMirrorMapping(PoseWranglerSettingsError):
 | 
			
		||||
    """
 | 
			
		||||
    Raised when the mirror mapping is incorrect
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
class PoseWranglerIOError(PoseWranglerException):
 | 
			
		||||
    """
 | 
			
		||||
    Raised when issues with serialization/deserialization arise
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
class PoseWranglerFunctionalityNotImplemented(PoseWranglerException):
 | 
			
		||||
    """
 | 
			
		||||
    Raised when pose wrangler functionality hasn't been implemented yet
 | 
			
		||||
    """
 | 
			
		||||
							
								
								
									
										125
									
								
								Scripts/Animation/epic_pose_wrangler/model/mirror_mapping.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,125 @@
 | 
			
		||||
#  Copyright Epic Games, Inc. All Rights Reserved.
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Example Mapping (MetaHuman)
 | 
			
		||||
{
 | 
			
		||||
    # Regular expression to validate that the solver follows the correct naming convention for mirroring
 | 
			
		||||
    "solver_expression": "(?P<prefix>[a-zA-Z0-9]+)?(?P<side>_[lr]{1}_)(?P<suffix>[a-zA-Z0-9]+)",
 | 
			
		||||
    # Regular expression to validate that the joint follows the correct naming convention for mirroring
 | 
			
		||||
    "transform_expression": "(?P<prefix>[a-zA-Z0-9]+)?(?P<side>_[lr]{1}_)(?P<suffix>[a-zA-Z0-9]+)",
 | 
			
		||||
    "left": {
 | 
			
		||||
        # Left side syntax for the solver
 | 
			
		||||
        "solver_syntax": "_l_",
 | 
			
		||||
        # Left side syntax for the joint
 | 
			
		||||
        "transform_syntax": "_l_"
 | 
			
		||||
    },
 | 
			
		||||
    "right": {
 | 
			
		||||
        # Right side syntax for the solver
 | 
			
		||||
        "solver_syntax": "_r_",
 | 
			
		||||
        # Right side syntax for the joint
 | 
			
		||||
        "transform_syntax": "_r_"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
"""
 | 
			
		||||
import json
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from epic_pose_wrangler.log import LOG
 | 
			
		||||
 | 
			
		||||
class MirrorMapping(object):
 | 
			
		||||
    """
 | 
			
		||||
    Class for managing mirror settings
 | 
			
		||||
    """
 | 
			
		||||
    LEFT = "left"
 | 
			
		||||
    RIGHT = "right"
 | 
			
		||||
 | 
			
		||||
    def __init__(self, file_path=None, source_side="left"):
 | 
			
		||||
        # Make a list of valid mappings that should exist in the mirror mapping file
 | 
			
		||||
        self._valid_mappings = [MirrorMapping.LEFT, MirrorMapping.RIGHT]
 | 
			
		||||
        # If no file path is specified, use the MetaHuman config as the fallback
 | 
			
		||||
        if file_path is None:
 | 
			
		||||
            LOG.debug("No mirror mapping specified, using default MetaHuman conventions")
 | 
			
		||||
            file_path = os.path.join(
 | 
			
		||||
                os.path.dirname(os.path.dirname(__file__)),
 | 
			
		||||
                'resources',
 | 
			
		||||
                'mirror_mappings',
 | 
			
		||||
                'metahuman.json'
 | 
			
		||||
            )
 | 
			
		||||
        self._file_path = file_path
 | 
			
		||||
        # Load the json mapping data
 | 
			
		||||
        with open(file_path, 'r') as f:
 | 
			
		||||
            self._mapping_data = json.loads(f.read())
 | 
			
		||||
 | 
			
		||||
        # Set the solver expression from the file
 | 
			
		||||
        self._solver_expression = self._mapping_data['solver_expression']
 | 
			
		||||
        # Set the transform expression from the file
 | 
			
		||||
        self._transform_expression = self._mapping_data['transform_expression']
 | 
			
		||||
 | 
			
		||||
        # Set the source side and create defaults
 | 
			
		||||
        self._source_side = source_side
 | 
			
		||||
        self._source_mapping_data = {}
 | 
			
		||||
        self._source_solver_syntax = ""
 | 
			
		||||
        self._source_transform_syntax = ""
 | 
			
		||||
 | 
			
		||||
        self._target_mapping_data = {}
 | 
			
		||||
        self._target_solver_syntax = ""
 | 
			
		||||
        self._target_transform_syntax = ""
 | 
			
		||||
        # Set the source side property to trigger the default values to be updated
 | 
			
		||||
        self.source_side = source_side
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def file_path(self):
 | 
			
		||||
        return self._file_path
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def solver_expression(self):
 | 
			
		||||
        return self._solver_expression
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def transform_expression(self):
 | 
			
		||||
        return self._transform_expression
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def source_side(self):
 | 
			
		||||
        return self._source_side
 | 
			
		||||
 | 
			
		||||
    @source_side.setter
 | 
			
		||||
    def source_side(self, side):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the source side and updates the source/target values accordingly
 | 
			
		||||
        :param side: MirrorMapping.LEFT or MirrorMapping.RIGHT
 | 
			
		||||
        """
 | 
			
		||||
        if side not in self._valid_mappings:
 | 
			
		||||
            raise ValueError("Invalid side specified, options are: {}".format(", ".join(self._valid_mappings)))
 | 
			
		||||
        self._source_side = side
 | 
			
		||||
        self._source_mapping_data = self._mapping_data[self._source_side]
 | 
			
		||||
        self._source_solver_syntax = self._source_mapping_data['solver_syntax']
 | 
			
		||||
        self._source_transform_syntax = self._source_mapping_data['transform_syntax']
 | 
			
		||||
 | 
			
		||||
        self._target_mapping_data = self._mapping_data[
 | 
			
		||||
            MirrorMapping.RIGHT if self._source_side == MirrorMapping.LEFT else MirrorMapping.LEFT]
 | 
			
		||||
        self._target_solver_syntax = self._target_mapping_data['solver_syntax']
 | 
			
		||||
        self._target_transform_syntax = self._target_mapping_data['transform_syntax']
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def source_solver_syntax(self):
 | 
			
		||||
        return self._source_solver_syntax
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def source_transform_syntax(self):
 | 
			
		||||
        return self._source_transform_syntax
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def target_solver_syntax(self):
 | 
			
		||||
        return self._target_solver_syntax
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def target_transform_syntax(self):
 | 
			
		||||
        return self._target_transform_syntax
 | 
			
		||||
 | 
			
		||||
    def swap_sides(self):
 | 
			
		||||
        """
 | 
			
		||||
        Swap the source side to the opposite of the current side.
 | 
			
		||||
        """
 | 
			
		||||
        new_target = MirrorMapping.LEFT if self.source_side == MirrorMapping.RIGHT else MirrorMapping.RIGHT
 | 
			
		||||
        self.source_side = new_target
 | 
			
		||||
							
								
								
									
										110
									
								
								Scripts/Animation/epic_pose_wrangler/model/plugin_manager.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,110 @@
 | 
			
		||||
#  Copyright Epic Games, Inc. All Rights Reserved.
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
 | 
			
		||||
from maya import cmds
 | 
			
		||||
 | 
			
		||||
from epic_pose_wrangler.log import LOG
 | 
			
		||||
from epic_pose_wrangler.model import exceptions
 | 
			
		||||
 | 
			
		||||
class PluginManager:
 | 
			
		||||
    """
 | 
			
		||||
    Class for loading latest available plugin and managing pose_wrangler versions
 | 
			
		||||
    """
 | 
			
		||||
    # The name of the recommended solver
 | 
			
		||||
    RECOMMENDED_SOLVER = "UERBFSolverNode"
 | 
			
		||||
    # Empty list to keep track of the loaded solver nodes
 | 
			
		||||
    LOADED_NODES = []
 | 
			
		||||
    # Generate an ordered manifest of known plugin name variants with the newest plugins
 | 
			
		||||
    __PLUGIN_VERSIONS = OrderedDict(
 | 
			
		||||
        {
 | 
			
		||||
            "MayaUERBFPlugin_{}".format(cmds.about(version=True)): "UERBFSolverNode",
 | 
			
		||||
            "MayaUERBFPlugin{}".format(cmds.about(version=True)): "UERBFSolverNode",
 | 
			
		||||
            "MayaUERBFPlugin": "UERBFSolverNode",
 | 
			
		||||
            "MayaUE4RBFPlugin_{}".format(cmds.about(version=True)): "UE4RBFSolverNode",
 | 
			
		||||
            "MayaUE4RBFPlugin{}".format(cmds.about(version=True)): "UE4RBFSolverNode",
 | 
			
		||||
            "MayaUE4RBFPlugin": "UE4RBFSolverNode"}
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def load_plugin():
 | 
			
		||||
        """
 | 
			
		||||
        Load any valid RBF plugins
 | 
			
		||||
        :return :type list: node names loaded
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        PluginManager.LOADED_NODES = []
 | 
			
		||||
        # Iterate through all of the valid plugin versions and attempt to load
 | 
			
		||||
        for plugin_name, solver_name in PluginManager.__PLUGIN_VERSIONS.items():
 | 
			
		||||
            # If the plugin is already loaded, add the solver name to the list of loaded nodes
 | 
			
		||||
            if cmds.pluginInfo(plugin_name, q=True, loaded=True) and solver_name not in PluginManager.LOADED_NODES:
 | 
			
		||||
                PluginManager.LOADED_NODES.append(solver_name)
 | 
			
		||||
            else:
 | 
			
		||||
                try:
 | 
			
		||||
                    # Attempt to load the plugin
 | 
			
		||||
                    cmds.loadPlugin(plugin_name)
 | 
			
		||||
                    # If the solver name is not already in the list, add it
 | 
			
		||||
                    if solver_name not in PluginManager.LOADED_NODES:
 | 
			
		||||
                        PluginManager.LOADED_NODES.append(solver_name)
 | 
			
		||||
                # Ignore errors
 | 
			
		||||
                except RuntimeError as e:
 | 
			
		||||
                    pass
 | 
			
		||||
        # If we have no loaded nodes no plugin loaded correctly
 | 
			
		||||
        if not PluginManager.LOADED_NODES:
 | 
			
		||||
            raise exceptions.InvalidPoseWranglerPlugin("Unable to load valid RBF plugin version.")
 | 
			
		||||
 | 
			
		||||
        return PluginManager.LOADED_NODES
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def is_scene_using_recommended_solver():
 | 
			
		||||
        """
 | 
			
		||||
        Scan the current scene to find which version of the solver is being used
 | 
			
		||||
        :return :type bool: is the recommended solver being used for all RBF nodes
 | 
			
		||||
        """
 | 
			
		||||
        solvers = []
 | 
			
		||||
        # Get a list of the solver names
 | 
			
		||||
        for solver_node_name in list(PluginManager.__PLUGIN_VERSIONS.values()):
 | 
			
		||||
            if solver_node_name not in solvers:
 | 
			
		||||
                solvers.append(solver_node_name)
 | 
			
		||||
        # Iterate through the solver names
 | 
			
		||||
        for solver_node_name in solvers:
 | 
			
		||||
            # Check if any solvers exist in the scene of the specified type and check if the solver name is the
 | 
			
		||||
            # recommended name. If we have old solvers in the scene, we aren't using the latest version.
 | 
			
		||||
            if cmds.ls(type=solver_node_name) and solver_node_name != PluginManager.RECOMMENDED_SOLVER:
 | 
			
		||||
                return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_pose_wrangler(view=True, parent=None, file_path=None):
 | 
			
		||||
        """
 | 
			
		||||
        Get the correct version of the pose wrangler tool depending on the available plugins and nodes in the scene
 | 
			
		||||
        :param view :type bool: Should we be displaying a UI to the user?
 | 
			
		||||
        :param parent :type main.PoseWrangler: reference to the main entry point for the tool, used for
 | 
			
		||||
        restarting/upgrading the tool
 | 
			
		||||
        :param file_path :type str: (optional) path to a json file containing serialized solver data
 | 
			
		||||
        :return :type object: reference to the currently loaded version of pose wrangler
 | 
			
		||||
        """
 | 
			
		||||
        # Load the RBF plugin
 | 
			
		||||
        loaded_nodes = PluginManager.load_plugin()
 | 
			
		||||
        # If the recommended solver is not loaded, fall back to the original pose wrangler implementation
 | 
			
		||||
        if PluginManager.RECOMMENDED_SOLVER not in loaded_nodes:
 | 
			
		||||
            LOG.warning("You are currently using an outdated plugin. Certain functionality may be limited.")
 | 
			
		||||
            from epic_pose_wrangler.v1 import main
 | 
			
		||||
            return main.UE4RBFAPI(view=view, parent=parent)
 | 
			
		||||
        # Bool to keep track of importing the newest api version
 | 
			
		||||
        import_failed = False
 | 
			
		||||
        # Check if the scene uses the latest solver
 | 
			
		||||
        if PluginManager.is_scene_using_recommended_solver():
 | 
			
		||||
            # Try and import the latest tool version
 | 
			
		||||
            try:
 | 
			
		||||
                from epic_pose_wrangler.v2 import main
 | 
			
		||||
                return main.UERBFAPI(view=view, parent=parent, file_path=file_path)
 | 
			
		||||
            except ImportError as e:
 | 
			
		||||
                LOG.error("Unable to import API v2, falling back to API v1 - {exception}".format(exception=e))
 | 
			
		||||
                import_failed = True
 | 
			
		||||
        # Fall back to API v1
 | 
			
		||||
        from epic_pose_wrangler.v1 import main
 | 
			
		||||
        # If the recommended solver is available but finds old nodes in the scene and imports correctly, provide
 | 
			
		||||
        # the option to upgrade to the latest version
 | 
			
		||||
        if not import_failed:
 | 
			
		||||
            main.UE4RBFAPI.UPGRADE_AVAILABLE = True
 | 
			
		||||
        return main.UE4RBFAPI(view=view, parent=parent)
 | 
			
		||||
							
								
								
									
										47
									
								
								Scripts/Animation/epic_pose_wrangler/model/settings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,47 @@
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from Qt import QtCore
 | 
			
		||||
 | 
			
		||||
from epic_pose_wrangler.log import LOG
 | 
			
		||||
from epic_pose_wrangler.model import exceptions
 | 
			
		||||
 | 
			
		||||
class SettingsManager(object):
 | 
			
		||||
    """
 | 
			
		||||
    Settings Manager for reading/writing to PoseWrangler settings ini file
 | 
			
		||||
    """
 | 
			
		||||
    QSETTINGS = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        # Initialize the QSettings
 | 
			
		||||
        QtCore.QSettings.setPath(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, os.environ['LOCALAPPDATA'])
 | 
			
		||||
        # Store the QSettings
 | 
			
		||||
        self.__class__.QSETTINGS = QtCore.QSettings(
 | 
			
		||||
            QtCore.QSettings.IniFormat,
 | 
			
		||||
            QtCore.QSettings.UserScope,
 | 
			
		||||
            "Epic Games",
 | 
			
		||||
            "PoseWrangler"
 | 
			
		||||
        )
 | 
			
		||||
        self.__class__.QSETTINGS.setFallbacksEnabled(False)
 | 
			
		||||
        LOG.debug("Successfully initialized SettingsManager")
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_setting(cls, name):
 | 
			
		||||
        """
 | 
			
		||||
        Get the setting with the specified name
 | 
			
		||||
        :param name :type str: setting name
 | 
			
		||||
        :return :type str or None: setting value
 | 
			
		||||
        """
 | 
			
		||||
        # If the settings haven't been initialized, raise exception
 | 
			
		||||
        if cls.QSETTINGS is None:
 | 
			
		||||
            raise exceptions.PoseWranglerSettingsError("Unable to load settings, "
 | 
			
		||||
                                                       "{cls} must be initialized first".format(cls=cls))
 | 
			
		||||
        return cls.QSETTINGS.value(name, None)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def set_setting(cls, name, value):
 | 
			
		||||
        """
 | 
			
		||||
        Add/Overwrite the setting with the specified name and value
 | 
			
		||||
        :param name :type str: setting name
 | 
			
		||||
        :param value :type any: setting value
 | 
			
		||||
        """
 | 
			
		||||
        cls.QSETTINGS.setValue(name, value)
 | 
			
		||||
@@ -0,0 +1,201 @@
 | 
			
		||||
import sys
 | 
			
		||||
import inspect
 | 
			
		||||
 | 
			
		||||
import maya
 | 
			
		||||
import maya.OpenMaya as OpenMaya
 | 
			
		||||
import maya.OpenMayaMPx as OpenMayaMPx
 | 
			
		||||
import maya.cmds as cmds
 | 
			
		||||
from pymel.core.windows import Callback, CallbackWithArgs
 | 
			
		||||
 | 
			
		||||
StreamTypesPerSubjectType = {
 | 
			
		||||
								"Prop": 		["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Character":	["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Camera":		["Root Only", "Full Hierarchy", "Camera"],
 | 
			
		||||
								"Light":		["Root Only", "Full Hierarchy", "Light"],
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
def OnRemoveSubject(SubjectPath):
 | 
			
		||||
	cmds.LiveLinkRemoveSubject(SubjectPath)
 | 
			
		||||
	RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
def CreateSubjectTable():
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", numberOfColumns=5, columnWidth=[(1, 20), (2,80), (3, 100), (4, 180), (5, 120)], columnOffset=[(1, 'right', 5), (2, 'right', 10), (4, 'left', 10)], parent="SubjectWrapperLayout")
 | 
			
		||||
	cmds.text(label="")
 | 
			
		||||
	cmds.text(label="Subject Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Subject Name", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="DAG Path", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Stream Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", edit=True, rowOffset=(1, "bottom", 10))
 | 
			
		||||
 | 
			
		||||
#Populate subjects list from c++
 | 
			
		||||
def PopulateSubjects():
 | 
			
		||||
	SubjectNames = cmds.LiveLinkSubjectNames()
 | 
			
		||||
	SubjectPaths = cmds.LiveLinkSubjectPaths()
 | 
			
		||||
	SubjectTypes = cmds.LiveLinkSubjectTypes()
 | 
			
		||||
	SubjectRoles = cmds.LiveLinkSubjectRoles()
 | 
			
		||||
	if SubjectPaths is not None:
 | 
			
		||||
		RowCounter = 0
 | 
			
		||||
		for (SubjectName, SubjectPath, SubjectType, SubjectRole) in zip(SubjectNames, SubjectPaths, SubjectTypes, SubjectRoles):
 | 
			
		||||
			cmds.button(label="-", height=21, command=Callback(OnRemoveSubject, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectType, height=21, align="left", parent="SubjectLayout")
 | 
			
		||||
			cmds.textField(text=SubjectName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectName, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectPath, align="left", height=21, parent="SubjectLayout")
 | 
			
		||||
 | 
			
		||||
			LayoutName = "ColumnLayoutRow_" + str(RowCounter) # adding a trailing index makes the name unique which is required by the api
 | 
			
		||||
 | 
			
		||||
			cmds.columnLayout(LayoutName, parent="SubjectLayout")
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", parent=LayoutName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectStreamType, SubjectPath))
 | 
			
		||||
			
 | 
			
		||||
			for StreamType in StreamTypesPerSubjectType[SubjectType]:
 | 
			
		||||
				cmds.menuItem(label=StreamType)
 | 
			
		||||
			
 | 
			
		||||
			StreamTypeIndex = StreamTypesPerSubjectType[SubjectType].index(SubjectRole) + 1 # menu items are 1-indexed
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", edit=True, select=StreamTypeIndex)
 | 
			
		||||
			
 | 
			
		||||
			RowCounter += 1
 | 
			
		||||
 | 
			
		||||
def ClearSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
 | 
			
		||||
#Refresh subjects list
 | 
			
		||||
def RefreshSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
#Connection UI Colours
 | 
			
		||||
ConnectionActiveColour = [0.71, 0.9, 0.1]
 | 
			
		||||
ConnectionInactiveColour = [1.0, 0.4, 0.4]
 | 
			
		||||
ConnectionColourMap = {
 | 
			
		||||
	True : ConnectionActiveColour,
 | 
			
		||||
	False: ConnectionInactiveColour
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Base class for command (common creator method + allows for automatic register/unregister)
 | 
			
		||||
class LiveLinkCommand(OpenMayaMPx.MPxCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		OpenMayaMPx.MPxCommand.__init__(self)
 | 
			
		||||
 | 
			
		||||
	@classmethod
 | 
			
		||||
	def Creator(Cls):
 | 
			
		||||
		return OpenMayaMPx.asMPxPtr( Cls() )
 | 
			
		||||
 | 
			
		||||
# Is supplied object a live link command
 | 
			
		||||
def IsLiveLinkCommand(InCls):
 | 
			
		||||
	return inspect.isclass(InCls) and issubclass(InCls, LiveLinkCommand) and InCls != LiveLinkCommand
 | 
			
		||||
 | 
			
		||||
# Given a list of strings of names return all the live link commands listed
 | 
			
		||||
def GetLiveLinkCommandsFromModule(ModuleItems):
 | 
			
		||||
	EvalItems = (eval(Item) for Item in ModuleItems)
 | 
			
		||||
	return [Command for Command in EvalItems if IsLiveLinkCommand(Command) ]
 | 
			
		||||
 | 
			
		||||
# Command to create the Live Link UI
 | 
			
		||||
class MayaLiveLinkUI(LiveLinkCommand):
 | 
			
		||||
	WindowName = "MayaLiveLinkUI"
 | 
			
		||||
	Title = "Maya Live Link UI"
 | 
			
		||||
	WindowSize = (500, 300)
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(self.WindowName , exists=True)):
 | 
			
		||||
			cmds.deleteUI(self.WindowName)
 | 
			
		||||
		window = cmds.window( self.WindowName, title=self.Title, widthHeight=(self.WindowSize[0], self.WindowSize[1]) )
 | 
			
		||||
		
 | 
			
		||||
		#Get current connection status
 | 
			
		||||
		ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
		
 | 
			
		||||
		cmds.columnLayout( "mainColumn", adjustableColumn=True )
 | 
			
		||||
		cmds.rowLayout("HeaderRow", numberOfColumns=3, adjustableColumn=1, parent = "mainColumn")
 | 
			
		||||
		cmds.text(label="Unreal Engine Live Link", align="left")
 | 
			
		||||
		cmds.text(label="Connection:")
 | 
			
		||||
		cmds.text("ConnectionStatusUI", label=ConnectionText, align="center", backgroundColor=ConnectionColourMap[ConnectedState], width=150)
 | 
			
		||||
		
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.columnLayout("SubjectWrapperLayout", parent="mainColumn") # just used as a container that will survive refreshing, so the following controls stay in their correct place
 | 
			
		||||
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.button( label='Add Selection', parent = "mainColumn", command=self.AddSelection)
 | 
			
		||||
 | 
			
		||||
		cmds.showWindow( self.WindowName )
 | 
			
		||||
 | 
			
		||||
	def AddSelection(self, *args):
 | 
			
		||||
		cmds.LiveLinkAddSelection()
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the subject UI
 | 
			
		||||
class MayaLiveLinkRefreshUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkClearUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
	
 | 
			
		||||
	def doIt(self, argList):
 | 
			
		||||
		ClearSubjects()
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the connection UI
 | 
			
		||||
class MayaLiveLinkRefreshConnectionUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
			#Get current connection status
 | 
			
		||||
			ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
			cmds.text("ConnectionStatusUI", edit=True, label=ConnectionText, backgroundColor=ConnectionColourMap[ConnectedState])
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkGetActiveCamera(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		self.clearResult()
 | 
			
		||||
		try:
 | 
			
		||||
			c = cmds.getPanel(wf=1)
 | 
			
		||||
			cam = cmds.modelPanel(c, q=True, camera=True)
 | 
			
		||||
		except:
 | 
			
		||||
			pass
 | 
			
		||||
		else:
 | 
			
		||||
			self.setResult(cam)
 | 
			
		||||
 | 
			
		||||
#Grab commands declared
 | 
			
		||||
Commands = GetLiveLinkCommandsFromModule(dir())
 | 
			
		||||
 | 
			
		||||
#Initialize the script plug-in
 | 
			
		||||
def initializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	print("LiveLink:"
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			print("\tRegistering Command '%s'"%Command.__name__
 | 
			
		||||
			mplugin.registerCommand( Command.__name__, Command.Creator )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to register command: %s\n" % Command.__name__ )
 | 
			
		||||
			raise
 | 
			
		||||
 | 
			
		||||
# Uninitialize the script plug-in
 | 
			
		||||
def uninitializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			mplugin.deregisterCommand( Command.__name__ )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to unregister command: %s\n" % Command.__name__ )
 | 
			
		||||
@@ -0,0 +1,201 @@
 | 
			
		||||
import sys
 | 
			
		||||
import inspect
 | 
			
		||||
 | 
			
		||||
import maya
 | 
			
		||||
import maya.OpenMaya as OpenMaya
 | 
			
		||||
import maya.OpenMayaMPx as OpenMayaMPx
 | 
			
		||||
import maya.cmds as cmds
 | 
			
		||||
from pymel.core.windows import Callback, CallbackWithArgs
 | 
			
		||||
 | 
			
		||||
StreamTypesPerSubjectType = {
 | 
			
		||||
								"Prop": 		["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Character":	["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Camera":		["Root Only", "Full Hierarchy", "Camera"],
 | 
			
		||||
								"Light":		["Root Only", "Full Hierarchy", "Light"],
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
def OnRemoveSubject(SubjectPath):
 | 
			
		||||
	cmds.LiveLinkRemoveSubject(SubjectPath)
 | 
			
		||||
	RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
def CreateSubjectTable():
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", numberOfColumns=5, columnWidth=[(1, 20), (2,80), (3, 100), (4, 180), (5, 120)], columnOffset=[(1, 'right', 5), (2, 'right', 10), (4, 'left', 10)], parent="SubjectWrapperLayout")
 | 
			
		||||
	cmds.text(label="")
 | 
			
		||||
	cmds.text(label="Subject Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Subject Name", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="DAG Path", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Stream Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", edit=True, rowOffset=(1, "bottom", 10))
 | 
			
		||||
 | 
			
		||||
#Populate subjects list from c++
 | 
			
		||||
def PopulateSubjects():
 | 
			
		||||
	SubjectNames = cmds.LiveLinkSubjectNames()
 | 
			
		||||
	SubjectPaths = cmds.LiveLinkSubjectPaths()
 | 
			
		||||
	SubjectTypes = cmds.LiveLinkSubjectTypes()
 | 
			
		||||
	SubjectRoles = cmds.LiveLinkSubjectRoles()
 | 
			
		||||
	if SubjectPaths is not None:
 | 
			
		||||
		RowCounter = 0
 | 
			
		||||
		for (SubjectName, SubjectPath, SubjectType, SubjectRole) in zip(SubjectNames, SubjectPaths, SubjectTypes, SubjectRoles):
 | 
			
		||||
			cmds.button(label="-", height=21, command=Callback(OnRemoveSubject, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectType, height=21, align="left", parent="SubjectLayout")
 | 
			
		||||
			cmds.textField(text=SubjectName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectName, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectPath, align="left", height=21, parent="SubjectLayout")
 | 
			
		||||
 | 
			
		||||
			LayoutName = "ColumnLayoutRow_" + str(RowCounter) # adding a trailing index makes the name unique which is required by the api
 | 
			
		||||
 | 
			
		||||
			cmds.columnLayout(LayoutName, parent="SubjectLayout")
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", parent=LayoutName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectStreamType, SubjectPath))
 | 
			
		||||
			
 | 
			
		||||
			for StreamType in StreamTypesPerSubjectType[SubjectType]:
 | 
			
		||||
				cmds.menuItem(label=StreamType)
 | 
			
		||||
			
 | 
			
		||||
			StreamTypeIndex = StreamTypesPerSubjectType[SubjectType].index(SubjectRole) + 1 # menu items are 1-indexed
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", edit=True, select=StreamTypeIndex)
 | 
			
		||||
			
 | 
			
		||||
			RowCounter += 1
 | 
			
		||||
 | 
			
		||||
def ClearSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
 | 
			
		||||
#Refresh subjects list
 | 
			
		||||
def RefreshSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
#Connection UI Colours
 | 
			
		||||
ConnectionActiveColour = [0.71, 0.9, 0.1]
 | 
			
		||||
ConnectionInactiveColour = [1.0, 0.4, 0.4]
 | 
			
		||||
ConnectionColourMap = {
 | 
			
		||||
	True : ConnectionActiveColour,
 | 
			
		||||
	False: ConnectionInactiveColour
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Base class for command (common creator method + allows for automatic register/unregister)
 | 
			
		||||
class LiveLinkCommand(OpenMayaMPx.MPxCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		OpenMayaMPx.MPxCommand.__init__(self)
 | 
			
		||||
 | 
			
		||||
	@classmethod
 | 
			
		||||
	def Creator(Cls):
 | 
			
		||||
		return OpenMayaMPx.asMPxPtr( Cls() )
 | 
			
		||||
 | 
			
		||||
# Is supplied object a live link command
 | 
			
		||||
def IsLiveLinkCommand(InCls):
 | 
			
		||||
	return inspect.isclass(InCls) and issubclass(InCls, LiveLinkCommand) and InCls != LiveLinkCommand
 | 
			
		||||
 | 
			
		||||
# Given a list of strings of names return all the live link commands listed
 | 
			
		||||
def GetLiveLinkCommandsFromModule(ModuleItems):
 | 
			
		||||
	EvalItems = (eval(Item) for Item in ModuleItems)
 | 
			
		||||
	return [Command for Command in EvalItems if IsLiveLinkCommand(Command) ]
 | 
			
		||||
 | 
			
		||||
# Command to create the Live Link UI
 | 
			
		||||
class MayaLiveLinkUI(LiveLinkCommand):
 | 
			
		||||
	WindowName = "MayaLiveLinkUI"
 | 
			
		||||
	Title = "Maya Live Link UI"
 | 
			
		||||
	WindowSize = (500, 300)
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(self.WindowName , exists=True)):
 | 
			
		||||
			cmds.deleteUI(self.WindowName)
 | 
			
		||||
		window = cmds.window( self.WindowName, title=self.Title, widthHeight=(self.WindowSize[0], self.WindowSize[1]) )
 | 
			
		||||
		
 | 
			
		||||
		#Get current connection status
 | 
			
		||||
		ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
		
 | 
			
		||||
		cmds.columnLayout( "mainColumn", adjustableColumn=True )
 | 
			
		||||
		cmds.rowLayout("HeaderRow", numberOfColumns=3, adjustableColumn=1, parent = "mainColumn")
 | 
			
		||||
		cmds.text(label="Unreal Engine Live Link", align="left")
 | 
			
		||||
		cmds.text(label="Connection:")
 | 
			
		||||
		cmds.text("ConnectionStatusUI", label=ConnectionText, align="center", backgroundColor=ConnectionColourMap[ConnectedState], width=150)
 | 
			
		||||
		
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.columnLayout("SubjectWrapperLayout", parent="mainColumn") # just used as a container that will survive refreshing, so the following controls stay in their correct place
 | 
			
		||||
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.button( label='Add Selection', parent = "mainColumn", command=self.AddSelection)
 | 
			
		||||
 | 
			
		||||
		cmds.showWindow( self.WindowName )
 | 
			
		||||
 | 
			
		||||
	def AddSelection(self, *args):
 | 
			
		||||
		cmds.LiveLinkAddSelection()
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the subject UI
 | 
			
		||||
class MayaLiveLinkRefreshUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkClearUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
	
 | 
			
		||||
	def doIt(self, argList):
 | 
			
		||||
		ClearSubjects()
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the connection UI
 | 
			
		||||
class MayaLiveLinkRefreshConnectionUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
			#Get current connection status
 | 
			
		||||
			ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
			cmds.text("ConnectionStatusUI", edit=True, label=ConnectionText, backgroundColor=ConnectionColourMap[ConnectedState])
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkGetActiveCamera(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		self.clearResult()
 | 
			
		||||
		try:
 | 
			
		||||
			c = cmds.getPanel(wf=1)
 | 
			
		||||
			cam = cmds.modelPanel(c, q=True, camera=True)
 | 
			
		||||
		except:
 | 
			
		||||
			pass
 | 
			
		||||
		else:
 | 
			
		||||
			self.setResult(cam)
 | 
			
		||||
 | 
			
		||||
#Grab commands declared
 | 
			
		||||
Commands = GetLiveLinkCommandsFromModule(dir())
 | 
			
		||||
 | 
			
		||||
#Initialize the script plug-in
 | 
			
		||||
def initializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	print("LiveLink:"
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			print("\tRegistering Command '%s'"%Command.__name__
 | 
			
		||||
			mplugin.registerCommand( Command.__name__, Command.Creator )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to register command: %s\n" % Command.__name__ )
 | 
			
		||||
			raise
 | 
			
		||||
 | 
			
		||||
# Uninitialize the script plug-in
 | 
			
		||||
def uninitializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			mplugin.deregisterCommand( Command.__name__ )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to unregister command: %s\n" % Command.__name__ )
 | 
			
		||||
@@ -0,0 +1,201 @@
 | 
			
		||||
import sys
 | 
			
		||||
import inspect
 | 
			
		||||
 | 
			
		||||
import maya
 | 
			
		||||
import maya.OpenMaya as OpenMaya
 | 
			
		||||
import maya.OpenMayaMPx as OpenMayaMPx
 | 
			
		||||
import maya.cmds as cmds
 | 
			
		||||
from pymel.core.windows import Callback, CallbackWithArgs
 | 
			
		||||
 | 
			
		||||
StreamTypesPerSubjectType = {
 | 
			
		||||
								"Prop": 		["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Character":	["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Camera":		["Root Only", "Full Hierarchy", "Camera"],
 | 
			
		||||
								"Light":		["Root Only", "Full Hierarchy", "Light"],
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
def OnRemoveSubject(SubjectPath):
 | 
			
		||||
	cmds.LiveLinkRemoveSubject(SubjectPath)
 | 
			
		||||
	RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
def CreateSubjectTable():
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", numberOfColumns=5, columnWidth=[(1, 20), (2,80), (3, 100), (4, 180), (5, 120)], columnOffset=[(1, 'right', 5), (2, 'right', 10), (4, 'left', 10)], parent="SubjectWrapperLayout")
 | 
			
		||||
	cmds.text(label="")
 | 
			
		||||
	cmds.text(label="Subject Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Subject Name", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="DAG Path", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Stream Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", edit=True, rowOffset=(1, "bottom", 10))
 | 
			
		||||
 | 
			
		||||
#Populate subjects list from c++
 | 
			
		||||
def PopulateSubjects():
 | 
			
		||||
	SubjectNames = cmds.LiveLinkSubjectNames()
 | 
			
		||||
	SubjectPaths = cmds.LiveLinkSubjectPaths()
 | 
			
		||||
	SubjectTypes = cmds.LiveLinkSubjectTypes()
 | 
			
		||||
	SubjectRoles = cmds.LiveLinkSubjectRoles()
 | 
			
		||||
	if SubjectPaths is not None:
 | 
			
		||||
		RowCounter = 0
 | 
			
		||||
		for (SubjectName, SubjectPath, SubjectType, SubjectRole) in zip(SubjectNames, SubjectPaths, SubjectTypes, SubjectRoles):
 | 
			
		||||
			cmds.button(label="-", height=21, command=Callback(OnRemoveSubject, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectType, height=21, align="left", parent="SubjectLayout")
 | 
			
		||||
			cmds.textField(text=SubjectName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectName, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectPath, align="left", height=21, parent="SubjectLayout")
 | 
			
		||||
 | 
			
		||||
			LayoutName = "ColumnLayoutRow_" + str(RowCounter) # adding a trailing index makes the name unique which is required by the api
 | 
			
		||||
 | 
			
		||||
			cmds.columnLayout(LayoutName, parent="SubjectLayout")
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", parent=LayoutName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectStreamType, SubjectPath))
 | 
			
		||||
			
 | 
			
		||||
			for StreamType in StreamTypesPerSubjectType[SubjectType]:
 | 
			
		||||
				cmds.menuItem(label=StreamType)
 | 
			
		||||
			
 | 
			
		||||
			StreamTypeIndex = StreamTypesPerSubjectType[SubjectType].index(SubjectRole) + 1 # menu items are 1-indexed
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", edit=True, select=StreamTypeIndex)
 | 
			
		||||
			
 | 
			
		||||
			RowCounter += 1
 | 
			
		||||
 | 
			
		||||
def ClearSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
 | 
			
		||||
#Refresh subjects list
 | 
			
		||||
def RefreshSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
#Connection UI Colours
 | 
			
		||||
ConnectionActiveColour = [0.71, 0.9, 0.1]
 | 
			
		||||
ConnectionInactiveColour = [1.0, 0.4, 0.4]
 | 
			
		||||
ConnectionColourMap = {
 | 
			
		||||
	True : ConnectionActiveColour,
 | 
			
		||||
	False: ConnectionInactiveColour
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Base class for command (common creator method + allows for automatic register/unregister)
 | 
			
		||||
class LiveLinkCommand(OpenMayaMPx.MPxCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		OpenMayaMPx.MPxCommand.__init__(self)
 | 
			
		||||
 | 
			
		||||
	@classmethod
 | 
			
		||||
	def Creator(Cls):
 | 
			
		||||
		return OpenMayaMPx.asMPxPtr( Cls() )
 | 
			
		||||
 | 
			
		||||
# Is supplied object a live link command
 | 
			
		||||
def IsLiveLinkCommand(InCls):
 | 
			
		||||
	return inspect.isclass(InCls) and issubclass(InCls, LiveLinkCommand) and InCls != LiveLinkCommand
 | 
			
		||||
 | 
			
		||||
# Given a list of strings of names return all the live link commands listed
 | 
			
		||||
def GetLiveLinkCommandsFromModule(ModuleItems):
 | 
			
		||||
	EvalItems = (eval(Item) for Item in ModuleItems)
 | 
			
		||||
	return [Command for Command in EvalItems if IsLiveLinkCommand(Command) ]
 | 
			
		||||
 | 
			
		||||
# Command to create the Live Link UI
 | 
			
		||||
class MayaLiveLinkUI(LiveLinkCommand):
 | 
			
		||||
	WindowName = "MayaLiveLinkUI"
 | 
			
		||||
	Title = "Maya Live Link UI"
 | 
			
		||||
	WindowSize = (500, 300)
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(self.WindowName , exists=True)):
 | 
			
		||||
			cmds.deleteUI(self.WindowName)
 | 
			
		||||
		window = cmds.window( self.WindowName, title=self.Title, widthHeight=(self.WindowSize[0], self.WindowSize[1]) )
 | 
			
		||||
		
 | 
			
		||||
		#Get current connection status
 | 
			
		||||
		ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
		
 | 
			
		||||
		cmds.columnLayout( "mainColumn", adjustableColumn=True )
 | 
			
		||||
		cmds.rowLayout("HeaderRow", numberOfColumns=3, adjustableColumn=1, parent = "mainColumn")
 | 
			
		||||
		cmds.text(label="Unreal Engine Live Link", align="left")
 | 
			
		||||
		cmds.text(label="Connection:")
 | 
			
		||||
		cmds.text("ConnectionStatusUI", label=ConnectionText, align="center", backgroundColor=ConnectionColourMap[ConnectedState], width=150)
 | 
			
		||||
		
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.columnLayout("SubjectWrapperLayout", parent="mainColumn") # just used as a container that will survive refreshing, so the following controls stay in their correct place
 | 
			
		||||
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.button( label='Add Selection', parent = "mainColumn", command=self.AddSelection)
 | 
			
		||||
 | 
			
		||||
		cmds.showWindow( self.WindowName )
 | 
			
		||||
 | 
			
		||||
	def AddSelection(self, *args):
 | 
			
		||||
		cmds.LiveLinkAddSelection()
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the subject UI
 | 
			
		||||
class MayaLiveLinkRefreshUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkClearUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
	
 | 
			
		||||
	def doIt(self, argList):
 | 
			
		||||
		ClearSubjects()
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the connection UI
 | 
			
		||||
class MayaLiveLinkRefreshConnectionUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
			#Get current connection status
 | 
			
		||||
			ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
			cmds.text("ConnectionStatusUI", edit=True, label=ConnectionText, backgroundColor=ConnectionColourMap[ConnectedState])
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkGetActiveCamera(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		self.clearResult()
 | 
			
		||||
		try:
 | 
			
		||||
			c = cmds.getPanel(wf=1)
 | 
			
		||||
			cam = cmds.modelPanel(c, q=True, camera=True)
 | 
			
		||||
		except:
 | 
			
		||||
			pass
 | 
			
		||||
		else:
 | 
			
		||||
			self.setResult(cam)
 | 
			
		||||
 | 
			
		||||
#Grab commands declared
 | 
			
		||||
Commands = GetLiveLinkCommandsFromModule(dir())
 | 
			
		||||
 | 
			
		||||
#Initialize the script plug-in
 | 
			
		||||
def initializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	print("LiveLink:"
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			print("\tRegistering Command '%s'"%Command.__name__
 | 
			
		||||
			mplugin.registerCommand( Command.__name__, Command.Creator )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to register command: %s\n" % Command.__name__ )
 | 
			
		||||
			raise
 | 
			
		||||
 | 
			
		||||
# Uninitialize the script plug-in
 | 
			
		||||
def uninitializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			mplugin.deregisterCommand( Command.__name__ )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to unregister command: %s\n" % Command.__name__ )
 | 
			
		||||
@@ -0,0 +1,203 @@
 | 
			
		||||
from __future__ import print_function
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import inspect
 | 
			
		||||
 | 
			
		||||
import maya
 | 
			
		||||
import maya.OpenMaya as OpenMaya
 | 
			
		||||
import maya.OpenMayaMPx as OpenMayaMPx
 | 
			
		||||
import maya.cmds as cmds
 | 
			
		||||
from pymel.core.windows import Callback, CallbackWithArgs
 | 
			
		||||
 | 
			
		||||
StreamTypesPerSubjectType = {
 | 
			
		||||
								"Prop": 		["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Character":	["Root Only", "Full Hierarchy"],
 | 
			
		||||
								"Camera":		["Root Only", "Full Hierarchy", "Camera"],
 | 
			
		||||
								"Light":		["Root Only", "Full Hierarchy", "Light"],
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
def OnRemoveSubject(SubjectPath):
 | 
			
		||||
	cmds.LiveLinkRemoveSubject(SubjectPath)
 | 
			
		||||
	RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
def CreateSubjectTable():
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", numberOfColumns=5, columnWidth=[(1, 20), (2,80), (3, 100), (4, 180), (5, 120)], columnOffset=[(1, 'right', 5), (2, 'right', 10), (4, 'left', 10)], parent="SubjectWrapperLayout")
 | 
			
		||||
	cmds.text(label="")
 | 
			
		||||
	cmds.text(label="Subject Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Subject Name", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="DAG Path", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.text(label="Stream Type", font="boldLabelFont", align="left")
 | 
			
		||||
	cmds.rowColumnLayout("SubjectLayout", edit=True, rowOffset=(1, "bottom", 10))
 | 
			
		||||
 | 
			
		||||
#Populate subjects list from c++
 | 
			
		||||
def PopulateSubjects():
 | 
			
		||||
	SubjectNames = cmds.LiveLinkSubjectNames()
 | 
			
		||||
	SubjectPaths = cmds.LiveLinkSubjectPaths()
 | 
			
		||||
	SubjectTypes = cmds.LiveLinkSubjectTypes()
 | 
			
		||||
	SubjectRoles = cmds.LiveLinkSubjectRoles()
 | 
			
		||||
	if SubjectPaths is not None:
 | 
			
		||||
		RowCounter = 0
 | 
			
		||||
		for (SubjectName, SubjectPath, SubjectType, SubjectRole) in zip(SubjectNames, SubjectPaths, SubjectTypes, SubjectRoles):
 | 
			
		||||
			cmds.button(label="-", height=21, command=Callback(OnRemoveSubject, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectType, height=21, align="left", parent="SubjectLayout")
 | 
			
		||||
			cmds.textField(text=SubjectName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectName, SubjectPath), parent="SubjectLayout")
 | 
			
		||||
			cmds.text(label=SubjectPath, align="left", height=21, parent="SubjectLayout")
 | 
			
		||||
 | 
			
		||||
			LayoutName = "ColumnLayoutRow_" + str(RowCounter) # adding a trailing index makes the name unique which is required by the api
 | 
			
		||||
 | 
			
		||||
			cmds.columnLayout(LayoutName, parent="SubjectLayout")
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", parent=LayoutName, height=21, changeCommand=CallbackWithArgs(cmds.LiveLinkChangeSubjectStreamType, SubjectPath))
 | 
			
		||||
			
 | 
			
		||||
			for StreamType in StreamTypesPerSubjectType[SubjectType]:
 | 
			
		||||
				cmds.menuItem(label=StreamType)
 | 
			
		||||
			
 | 
			
		||||
			StreamTypeIndex = StreamTypesPerSubjectType[SubjectType].index(SubjectRole) + 1 # menu items are 1-indexed
 | 
			
		||||
			cmds.optionMenu("SubjectTypeMenu", edit=True, select=StreamTypeIndex)
 | 
			
		||||
			
 | 
			
		||||
			RowCounter += 1
 | 
			
		||||
 | 
			
		||||
def ClearSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
 | 
			
		||||
#Refresh subjects list
 | 
			
		||||
def RefreshSubjects():
 | 
			
		||||
	if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
		cmds.deleteUI("SubjectLayout")
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
#Connection UI Colours
 | 
			
		||||
ConnectionActiveColour = [0.71, 0.9, 0.1]
 | 
			
		||||
ConnectionInactiveColour = [1.0, 0.4, 0.4]
 | 
			
		||||
ConnectionColourMap = {
 | 
			
		||||
	True : ConnectionActiveColour,
 | 
			
		||||
	False: ConnectionInactiveColour
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Base class for command (common creator method + allows for automatic register/unregister)
 | 
			
		||||
class LiveLinkCommand(OpenMayaMPx.MPxCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		OpenMayaMPx.MPxCommand.__init__(self)
 | 
			
		||||
 | 
			
		||||
	@classmethod
 | 
			
		||||
	def Creator(Cls):
 | 
			
		||||
		return OpenMayaMPx.asMPxPtr( Cls() )
 | 
			
		||||
 | 
			
		||||
# Is supplied object a live link command
 | 
			
		||||
def IsLiveLinkCommand(InCls):
 | 
			
		||||
	return inspect.isclass(InCls) and issubclass(InCls, LiveLinkCommand) and InCls != LiveLinkCommand
 | 
			
		||||
 | 
			
		||||
# Given a list of strings of names return all the live link commands listed
 | 
			
		||||
def GetLiveLinkCommandsFromModule(ModuleItems):
 | 
			
		||||
	EvalItems = (eval(Item) for Item in ModuleItems)
 | 
			
		||||
	return [Command for Command in EvalItems if IsLiveLinkCommand(Command) ]
 | 
			
		||||
 | 
			
		||||
# Command to create the Live Link UI
 | 
			
		||||
class MayaLiveLinkUI(LiveLinkCommand):
 | 
			
		||||
	WindowName = "MayaLiveLinkUI"
 | 
			
		||||
	Title = "Maya Live Link UI"
 | 
			
		||||
	WindowSize = (500, 300)
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(self.WindowName , exists=True)):
 | 
			
		||||
			cmds.deleteUI(self.WindowName)
 | 
			
		||||
		window = cmds.window( self.WindowName, title=self.Title, widthHeight=(self.WindowSize[0], self.WindowSize[1]) )
 | 
			
		||||
		
 | 
			
		||||
		#Get current connection status
 | 
			
		||||
		ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
		
 | 
			
		||||
		cmds.columnLayout( "mainColumn", adjustableColumn=True )
 | 
			
		||||
		cmds.rowLayout("HeaderRow", numberOfColumns=3, adjustableColumn=1, parent = "mainColumn")
 | 
			
		||||
		cmds.text(label="Unreal Engine Live Link", align="left")
 | 
			
		||||
		cmds.text(label="Connection:")
 | 
			
		||||
		cmds.text("ConnectionStatusUI", label=ConnectionText, align="center", backgroundColor=ConnectionColourMap[ConnectedState], width=150)
 | 
			
		||||
		
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.columnLayout("SubjectWrapperLayout", parent="mainColumn") # just used as a container that will survive refreshing, so the following controls stay in their correct place
 | 
			
		||||
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
		PopulateSubjects()
 | 
			
		||||
 | 
			
		||||
		cmds.separator(h=20, style="none", parent="mainColumn")
 | 
			
		||||
		cmds.button( label='Add Selection', parent = "mainColumn", command=self.AddSelection)
 | 
			
		||||
 | 
			
		||||
		cmds.showWindow( self.WindowName )
 | 
			
		||||
 | 
			
		||||
	def AddSelection(self, *args):
 | 
			
		||||
		cmds.LiveLinkAddSelection()
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the subject UI
 | 
			
		||||
class MayaLiveLinkRefreshUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		RefreshSubjects()
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkClearUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
	
 | 
			
		||||
	def doIt(self, argList):
 | 
			
		||||
		ClearSubjects()
 | 
			
		||||
		CreateSubjectTable()
 | 
			
		||||
 | 
			
		||||
# Command to Refresh the connection UI
 | 
			
		||||
class MayaLiveLinkRefreshConnectionUI(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		if (cmds.window(MayaLiveLinkUI.WindowName , exists=True)):
 | 
			
		||||
			#Get current connection status
 | 
			
		||||
			ConnectionText, ConnectedState = cmds.LiveLinkConnectionStatus()
 | 
			
		||||
			cmds.text("ConnectionStatusUI", edit=True, label=ConnectionText, backgroundColor=ConnectionColourMap[ConnectedState])
 | 
			
		||||
 | 
			
		||||
class MayaLiveLinkGetActiveCamera(LiveLinkCommand):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		LiveLinkCommand.__init__(self)
 | 
			
		||||
		
 | 
			
		||||
	# Invoked when the command is run.
 | 
			
		||||
	def doIt(self,argList):
 | 
			
		||||
		self.clearResult()
 | 
			
		||||
		try:
 | 
			
		||||
			c = cmds.getPanel(wf=1)
 | 
			
		||||
			cam = cmds.modelPanel(c, q=True, camera=True)
 | 
			
		||||
		except:
 | 
			
		||||
			pass
 | 
			
		||||
		else:
 | 
			
		||||
			self.setResult(cam)
 | 
			
		||||
 | 
			
		||||
#Grab commands declared
 | 
			
		||||
Commands = GetLiveLinkCommandsFromModule(dir())
 | 
			
		||||
 | 
			
		||||
#Initialize the script plug-in
 | 
			
		||||
def initializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	print("LiveLink:")
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			print("\tRegistering Command '%s'"%Command.__name__)
 | 
			
		||||
			mplugin.registerCommand( Command.__name__, Command.Creator )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to register command: %s\n" % Command.__name__ )
 | 
			
		||||
			raise
 | 
			
		||||
 | 
			
		||||
# Uninitialize the script plug-in
 | 
			
		||||
def uninitializePlugin(mobject):
 | 
			
		||||
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 | 
			
		||||
 | 
			
		||||
	for Command in Commands:
 | 
			
		||||
		try:
 | 
			
		||||
			mplugin.deregisterCommand( Command.__name__ )
 | 
			
		||||
		except:
 | 
			
		||||
			sys.stderr.write( "Failed to unregister command: %s\n" % Command.__name__ )
 | 
			
		||||