Update
This commit is contained in:
parent
b70480685d
commit
908f9b94af
@ -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
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Úµ–MoÛ0†ïþÖkŒ®ÇÞ6,rh´èvd‹±è’œÆûõ“"Åv²`C,ïfPäCê5EI+øÃÙp0åþ¡„Éò}ýúõû—íéþ±æÄZôÍÊÖ þé
|
||||||
|
ý×°òÇúõmóò‰s†U<E280A0>ƒ„R\q<>Ô¶DC p¢30Ô°=H켓Ý)#l>ÍÌgÔˆƒ%ö–HÁ+—aª¶Šû<C5A0>Í'uÆ€tŒ6Jƒqý<71>
|
||||||
|
–(‘²JŒ¢`Á0ÂÙ/X‚<58>wF ¼c|>
(sKè|ädªÒ2%mFë4àp¤ó°Ù…ÆP®zìúimì<6D>€“Däá*Šîˆël®cù’)ìTÞ1c~W<0B>E®<08>,˜1Ê`A´f²ÉhÅÊ%1˜=¢Ë<C2A2>ƒc9Ô€P{H7òüZ&”Œ›Ø_Wþ,æÉ’?ÒÇ<C392>îÏPÖ8·þ4ÿÙ¿³P<C2B3>¦ÙO‹=ƒ<>ÛZEù˶¬ˆ7¸Üz¯ŸÉi}²Nߥãűºô5^T½t8@ÄSa—Îᯮ4ÕqÝúE ÿ5Ý•}-EÐÖ:úHU<48>Vc; ß.Åä0q¹ !¥-<1A>LR8Ý9©€‡€“5ºoÂg1º%êÄ#ì<07>6„¾©ºþKœOQ\¦ à|%’žŽ6ôm…WïJyº_<C2BA>R”¢<E2809D>?ó±P?ÕÌQÊIª“-º?”÷å=zI¶b‚ûGžmï½<Og<4F>˜º=Œ¶ó×·¤<C2B7>¢Ó<C2A2>!ôB†Áýߧb¥Åoéaà
|
@ -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
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>
|
File diff suppressed because one or more lines are too long
@ -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
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)
|
31
Scripts/Animation/epic_pose_wrangler/main.py
Normal file
31
Scripts/Animation/epic_pose_wrangler/main.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# 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
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
|
43
Scripts/Animation/epic_pose_wrangler/model/exceptions.py
Normal file
43
Scripts/Animation/epic_pose_wrangler/model/exceptions.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# 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
|
||||||
|
"""
|
126
Scripts/Animation/epic_pose_wrangler/model/mirror_mapping.py
Normal file
126
Scripts/Animation/epic_pose_wrangler/model/mirror_mapping.py
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# 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
|
111
Scripts/Animation/epic_pose_wrangler/model/plugin_manager.py
Normal file
111
Scripts/Animation/epic_pose_wrangler/model/plugin_manager.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# 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)
|
48
Scripts/Animation/epic_pose_wrangler/model/settings.py
Normal file
48
Scripts/Animation/epic_pose_wrangler/model/settings.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from PySide2 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)
|
Binary file not shown.
@ -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__ )
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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__ )
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user