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++; } } }