Files
Nexus/plug-ins/ahoge/2025/scripts/ahogeTools.mel
2025-12-05 08:08:44 +08:00

485 lines
17 KiB
Plaintext

global proc ahogeTools()
{
if (`menu -exists ahogeToolsMenu`)
{
deleteUI ahogeToolsMenu;
}
else
{
menu -l "Ahoge"
-tearOff true
-p "MayaWindow" ahogeToolsMenu;
menuItem -l "Ahoge"
-c "python(\"import ahoge_ui;ahoge_ui.create_ahoge()\")"
-ann "Create an ahogeShape node with a random seed and connect the selected surfaces"
-i "ahogeShape.png"
-p ahogeToolsMenu;
menuItem -optionBox true
-c "python(\"import ahoge_ui;ahoge_ui.create_ahoge_options()\")"
-p ahogeToolsMenu;
menuItem -l "Connect"
-c "ahogeTools_connect"
-ann "Connect the selected nurbs surfaces to the selected ahogeShape nodes"
-i "ahoge_connect.png"
-p ahogeToolsMenu;
menuItem -l "Disconnect"
-c "ahogeTools_disconnect"
-ann "Disconnect the selected nurbs surfaces from the selected ahogeShape nodes"
-i "ahoge_disconnect.png"
-p ahogeToolsMenu;
menuItem -l "Duplicate"
-subMenu true
-ann "Duplicate ahogeShape nodes"
-i "ahoge_duplicate.png"
-p ahogeToolsMenu ahogeToolsMenu_duplicate_menu;
menuItem -l "Ahoge"
-c "ahogeTools_duplicateAhoge"
-ann "Duplicate the selected ahogeShape nodes and set random seeds"
-i "ahogeShape.png"
-p ahogeToolsMenu_duplicate_menu;
menuItem -l "Ahoge and Connect"
-c "ahogeTools_duplicateAhoge_connect"
-ann "Duplicate the selected ahogeShape nodes, connect the selected surfaces to them, and set random seeds"
-i "ahoge_connect.png"
-p ahogeToolsMenu_duplicate_menu;
menuItem -l "Extra"
-subMenu true
-ann "Extra nodes"
-i "ahoge_extra.png"
-p ahogeToolsMenu ahogeToolsMenu_extra_menu;
menuItem -l "Nurbopus"
-c "python(\"import ahoge_ui;ahoge_ui.create_nurbopus()\")"
-ann "Select curves and optionally a mesh to create Nurbopus"
-i "out_nurbopusNode.png"
-p ahogeToolsMenu_extra_menu;
menuItem -optionBox true
-c "python(\"import ahoge_ui;ahoge_ui.create_nurbopus_options()\")"
-p ahogeToolsMenu_extra_menu;
menuItem -l "Connect"
-c "ahogeTools_nurbopus_connect"
-ann "Select surfaces that have Nurbopus and curves to connect the selected curves to the Nurbopus node"
-i "ahoge_connect.png"
-p ahogeToolsMenu_extra_menu;
menuItem -l "Detach"
-c "ahogeTools_nurbopus_detach"
-ann "Disconnect the selected surfaces from their Nurbopus node, duplicate the Nurbopus node, and connect the duplicated Nurbopus node to the curves of the selected surfaces"
-i "ahoge_detach.png"
-p ahogeToolsMenu_extra_menu;
menuItem -l "Miscellaneous"
-subMenu true
-ann "Miscellaneous Tools"
-i "ahoge_misc.png"
-p ahogeToolsMenu ahogeToolsMenu_misc_menu;
menuItem -l "Fix Surfaces"
-c "ahogeTools_fixSurfaces"
-ann "Select Nurbs Surfaces and a Mesh to fix the Surfaces"
-i "ahoge_fix.png"
-p ahogeToolsMenu_misc_menu;
menuItem -l "Select Connected Surfaces"
-c "ahogeTools_selectConnectedSurfaces"
-ann "Select Nurbs Surfaces that are connected to the selected Ahoge Shapes"
-i "aselect.png"
-p ahogeToolsMenu_misc_menu;
menuItem -l "Disconnect Connected Surfaces"
-c "ahogeTools_disconnectConnectedSurfaces"
-ann "Disconnect Nurbs Surfaces that are connected to the selected Ahoge Shapes"
-i "ahoge_disconnect.png"
-p ahogeToolsMenu_misc_menu;
menuItem -l "Select"
-subMenu true
-ann "Select ahogeShape nodes"
-pmc "ahogeTools_select_pmc"
-i "aselect.png"
-p ahogeToolsMenu ahogeToolsMenu_select_menu;
menuItem -l "Convert"
-subMenu true
-ann "Convert ahogeShape nodes"
-i "ahoge_convert.png"
-p ahogeToolsMenu ahogeToolsMenu_convert_menu;
menuItem -l "Convert to Curves"
-c "ahogeTools_convertToCurves"
-ann "Convert the selected ahogeShape nodes to nurbs curves"
-i "curveEP.png"
-p ahogeToolsMenu_convert_menu;
menuItem -l "Export"
-subMenu true
-ann "Export ahogeShape nodes"
-i "ahoge_export.png"
-p ahogeToolsMenu ahogeToolsMenu_export_menu;
menuItem -l "Export Alembic"
-c "python(\"import ahoge_ui;ahoge_ui.export_alembic_options()\")"
-ann "Export ahogeShape nodes to Alembic"
-i "ahoge_abc.png"
-p ahogeToolsMenu_export_menu;
menuItem -d true -p ahogeToolsMenu;
menuItem -l "Support"
-c "ahogeTools_support"
-ann "Get support and updates"
-i "ahoge_info.png"
-p ahogeToolsMenu;
}
}
global proc ahogeTools_disconnect_attr( string $left, string $right )
{
string $connections[] = `listConnections -p true $left`;
string $connection;
for ($connection in $connections)
{
string $ending = `match "\[[0-9]+\]$" $connection`;
string $short = `substring $connection 1 (size($connection) - size($ending))`;
if ( $short == $right )
{
disconnectAttr $left $connection;
}
}
}
global proc ahogeTools_connect()
{
string $surfaces[] = `ls -sl -dag -type "nurbsSurface"`;
string $ahogeShapes[] = `ls -sl -dag -type "ahogeShape"`;
string $ahogeShape;
for ($ahogeShape in $ahogeShapes)
{
string $inputSurfaces[] = `listConnections -p true ($ahogeShape + ".inputSurfaces")`;
string $inputSurfacesObj[] = `listConnections -p false ($ahogeShape + ".inputSurfaces")`;
$inputSurfacesObj = `ls -dag -type "nurbsSurface" $inputSurfacesObj`;
string $connect;
for ($connect in $inputSurfaces)
{
ahogeTools_disconnect_attr $connect ($ahogeShape + ".inputSurfaces");
}
string $surfacesToAdd[] = {};
string $surface;
for ($surface in $surfaces)
{
if (!stringArrayContains($surface, $inputSurfacesObj))
{
$surfacesToAdd[size($surfacesToAdd)] = $surface;
}
}
string $diffSurfaces[] = stringArrayCatenate($inputSurfacesObj, $surfacesToAdd);
int $i = 0;
for (; $i < size($diffSurfaces); $i++ )
{
connectAttr ($diffSurfaces[$i] + ".worldSpace[0]") ($ahogeShape + ".inputSurfaces[" + $i + "]");
}
}
}
global proc ahogeTools_disconnect()
{
string $surfaces[] = `ls -sl -dag -type "nurbsSurface"`;
string $ahogeShapes[] = `ls -sl -dag -type "ahogeShape"`;
string $ahogeShape;
for ($ahogeShape in $ahogeShapes)
{
string $inputSurfaces[] = `listConnections -p true ($ahogeShape + ".inputSurfaces")`;
string $inputSurfacesObj[] = `listConnections -p false ($ahogeShape + ".inputSurfaces")`;
$inputSurfacesObj = `ls -dag -type "nurbsSurface" $inputSurfacesObj`;
string $connect;
for ($connect in $inputSurfaces)
{
ahogeTools_disconnect_attr $connect ($ahogeShape + ".inputSurfaces");
}
string $diffSurfaces[] = stringArrayRemove($surfaces, $inputSurfacesObj);
int $i = 0;
for (; $i < size($diffSurfaces); $i++ )
{
connectAttr ($diffSurfaces[$i] + ".worldSpace[0]") ($ahogeShape + ".inputSurfaces[" + $i + "]");
}
}
}
global proc ahogeTools_duplicateAhoge()
{
string $ahoges[] = `ls -dag -sl -l -type ahogeShape`;
string $ahoge;
for ($ahoge in $ahoges)
{
string $dup[] = `duplicate -ic $ahoge`;
setAttr ($dup[0] + ".seed") (int(rand(100000)));
}
}
global proc ahogeTools_duplicateAhoge_connect()
{
string $ahoges[] = `ls -dag -sl -l -type ahogeShape`;
string $surfaces[] = `ls -dag -sl -l -type nurbsSurface`;
if (size($ahoges) < 1) error "you haven't selected any ahogeShapes";
if (size($surfaces) < 1) error "you haven't selected any surfaces";
string $ahoge;
for ($ahoge in $ahoges)
{
string $dup[] = `duplicate $ahoge`;
string $multiInstances[] = `listAttr ($dup[0] + ".inputSurfaces[*]")`;
string $multiInstance;
for ($multiInstance in $multiInstances)
{
removeMultiInstance -b true ($dup[0] + "." + $multiInstance);
}
int $i = 0;
for (; $i < size($surfaces); $i++)
{
connectAttr -f ($surfaces[$i] + ".worldSpace[0]") ($dup[0] + ".inputSurfaces[" + $i + "]");
}
setAttr ($dup[0] + ".seed") (int(rand(100000)));
}
}
global proc ahogeTools_select_pmc()
{
menu -e -dai ahogeToolsMenu_select_menu;
string $ahogeShapes[] = `ls -l -type ahogeShape`;
string $ahogeShapesSelected[] = `ls -sl -dag -l -type ahogeShape`;
string $node;
for ($node in $ahogeShapes)
{
string $name[] = `listRelatives -parent $node`;
menuItem -cb (stringArrayContains($node, $ahogeShapesSelected)) -l $name[0] -c ("select " + $node) -p ahogeToolsMenu_select_menu;
}
if (!size($ahogeShapes)) menuItem -l "Nothing" -en false -p ahogeToolsMenu_select_menu;
}
global proc ahogeTools_convertToCurves()
{
string $ahogeShape[] = `ls -l -sl -dag -type "ahogeShape"`;
string $node;
for ($node in $ahogeShape)
{
int $num = `getAttr ($node + ".numSegments")` + 1;
float $cvs[] = `getAttr ($node + ".outputPoints")`;
string $parent[] = `listRelatives -f -parent $node`;
float $m[] = `xform -q -ws -m $parent[0]`;
int $numCurves = size($cvs) / $num / 3;
int $i = 0;
for (; $i < $numCurves; $i++)
{
string $curve = "curve -d 3";
int $j = 0;
for (; $j < $num; $j++)
{
vector $p = << $cvs[$i*$num*3+$j*3], $cvs[$i*$num*3+$j*3 + 1], $cvs[$i*$num*3+$j*3 + 2] >>;
$p = pointMatrixMult($p, $m);
$p += <<$m[12], $m[13], $m[14]>>;
$curve += " -p " + ($p.x) + " " + ($p.y) + " " + ($p.z);
}
eval $curve;
}
}
}
global proc ahogeTools_support()
{
python("import webbrowser;webbrowser.open('https://boosty.to/ahoge')");
}
// Misc
global proc float ahoge_distance(vector $v1, vector $v2)
{
return sqrt(pow(($v1.x) - ($v2.x), 2) + pow(($v1.y) - ($v2.y), 2) + pow(($v1.z) - ($v2.z), 2));
}
global proc ahogeTools_fixSurfaces()
{
string $surfaces[] = `ls -dag -sl -l -type nurbsSurface`;
string $meshes[] = `ls -dag -sl -l -type mesh`;
if (!size($surfaces)) error "No nurbsSurfaces selected";
if (size($meshes) != 1) error "Select a mesh";
string $surface;
for ($surface in $surfaces)
{
// reverse direction
if ((`getAttr ($surface + ".fu")` == 0) &&
((`getAttr ($surface + ".fv")` == 1) ||
(`getAttr ($surface + ".fv")` == 2)))
{
reverseSurface -d 3 -ch 0 -rpo 1 $surface;
reverseSurface -d 0 -ch 0 -rpo 1 $surface;
}
vector $first_point = << 0, 0, 0 >>;
vector $second_point = << 0, 0, 0 >>;
int $i = 0;
for (; $i < 4; $i++)
{
$first_point += `pointOnSurface -top true -u (float($i) / 4) -v 0.0 -position $surface`;
$second_point += `pointOnSurface -top true -u (float($i) / 4) -v 1.0 -position $surface`;
}
$first_point = $first_point / 4;
$second_point = $second_point / 4;
// check for inverted normals first
vector $norm = `pointOnSurface -u 0.0 -v 0.0 -nn $surface`;
vector $origin = `pointOnSurface -u 0.0 -v 0.0 -position $surface`;
if (dot($norm, $first_point - $origin) > 0)
{
reverseSurface -d 0 -ch 0 -rpo 1 $surface;
}
//print($first_point.x + " " + $first_point.y + " " + $first_point.z + "\n");
//print($second_point.x + " " + $second_point.y + " " + $second_point.z + "\n");
vector $first_point_surface = `ahogeCmd -m $meshes[0] -cp ($first_point.x) ($first_point.y) ($first_point.z)`;
vector $second_point_surface = `ahogeCmd -m $meshes[0] -cp ($second_point.x) ($second_point.y) ($second_point.z)`;
float $first_point_distance = ahoge_distance($first_point, $first_point_surface);
float $second_point_distance = ahoge_distance($second_point, $second_point_surface);
if ($first_point_distance < $second_point_distance) // needs to reverse V then
{
reverseSurface -d 1 -ch 0 -rpo 1 $surface;
reverseSurface -d 0 -ch 0 -rpo 1 $surface;
}
}
}
global proc ahogeTools_selectConnectedSurfaces()
{
string $ahogeShapes[] = `ls -sl -dag -type "ahogeShape"`;
string $result[] = {};
string $ahogeShape;
for ($ahogeShape in $ahogeShapes)
{
string $inputSurfacesObj[] = `listConnections -p false ($ahogeShape + ".inputSurfaces")`;
$inputSurfacesObj = `ls -dag -type "nurbsSurface" $inputSurfacesObj`;
string $surface;
for ($surface in $inputSurfacesObj)
{
$result[size($result)] = $surface;
}
}
select $result;
}
global proc ahogeTools_disconnectConnectedSurfaces()
{
string $ahogeShapes[] = `ls -sl -dag -type "ahogeShape"`;
string $ahogeShape;
for ($ahogeShape in $ahogeShapes)
{
string $inputSurfaces[] = `listConnections -p true ($ahogeShape + ".inputSurfaces")`;
string $connect;
for ($connect in $inputSurfaces)
{
ahogeTools_disconnect_attr $connect ($ahogeShape + ".inputSurfaces");
}
}
}
global proc ahogeTools_nurbopus_connect()
{
string $surfaces[] = `ls -sl -dag -type "nurbsSurface"`;
if (size($surfaces) == 0) error "No nurbsSurface selected";
string $history[] = `listHistory $surfaces`;
string $nurbopuses[] = `ls -type "nurbopusNode" $history`;
string $curves[] = `ls -sl -dag -type "nurbsCurve"`;
if (size($nurbopuses) == 0) error "No nurbopusNode selected";
if (size($curves) == 0) error "No nurbsCurve selected";
string $nurbopus;
for ($nurbopus in $nurbopuses)
{
int $size = `getAttr -size ($nurbopus + ".inputCurves")`;
int $i = 0;
for (; $i < size($curves); $i++)
{
connectAttr ($curves[$i] + ".worldSpace[0]") ($nurbopus + ".inputCurves[" + ($size + $i) + "]");
string $surface = `createNode "nurbsSurface"`;
connectAttr ($nurbopus + ".outputSurfaces[" + ($size + $i) + "]") ($surface + ".create");
hyperShade -assign "initialShadingGroup" $surface;
}
}
}
global proc int ahogeTools_extract(string $str)
{
string $str_idx = `match "\[[0-9]+\]$" $str`;
string $array[];
tokenize $str_idx "[]" $array;
return int($array[0]);
}
global proc ahogeTools_nurbopus_detach()
{
string $surfaces[] = `ls -sl -dag -type "nurbsSurface"`;
if (size($surfaces) == 0) error "No nurbsSurface selected";
string $history[] = `listHistory $surfaces`;
string $nurbopuses[] = `ls -type "nurbopusNode" $history`;
if (size($nurbopuses) == 0) error "No nurbopusNode selected";
if (size($nurbopuses) != 1) error "Detach only works with a single nurbopusNode";
string $duplicate[] = `duplicate $nurbopuses[0]`;
int $connectionIndices[] = {};
int $i = 0;
for (; $i < size($surfaces); $i++)
{
string $surfaceCreate[] = `listConnections -c true -p true ($surfaces[$i] + ".create")`;
$connectionIndices[size($connectionIndices)] = ahogeTools_extract($surfaceCreate[1]);
}
string $output_surfaces[] = `listConnections -p false ($nurbopuses[0] + ".outputSurfaces")`;
$output_surfaces = `ls -dag -type "nurbsSurface" $output_surfaces`;
string $inputCurves[] = `listConnections -p true ($nurbopuses[0] + ".inputCurves")`;
string $inputCurvesObj[] = `listConnections -p false ($nurbopuses[0] + ".inputCurves")`;
$inputCurvesObj = `ls -dag -type "nurbsCurve" $inputCurvesObj`;
string $connect;
for ($connect in $inputCurves)
{
ahogeTools_disconnect_attr $connect ($nurbopuses[0] + ".inputCurves");
}
int $first_count = 0;
int $second_count = 0;
for ($i = 0; $i < size($inputCurvesObj); $i++)
{
if (intArrayContains($i, $connectionIndices))
{
connectAttr ($inputCurvesObj[$i] + ".worldSpace[0]") ($duplicate[0] + ".inputCurves[" + $first_count + "]");
connectAttr -f ($duplicate[0] + ".outputSurfaces[" + $first_count + "]") ($output_surfaces[$i] + ".create");
$first_count++;
}
else
{
connectAttr ($inputCurvesObj[$i] + ".worldSpace[0]") ($nurbopuses[0] + ".inputCurves[" + $second_count + "]");
connectAttr -f ($nurbopuses[0] + ".outputSurfaces[" + $second_count + "]") ($output_surfaces[$i] + ".create");
$second_count++;
}
}
}