Update
BIN
plug-ins/ahoge/2025/icons/ahogeShape.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_abc.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
plug-ins/ahoge/2025/icons/ahoge_connect.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_convert.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_detach.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_disconnect.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_duplicate.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_export.png
Normal file
|
After Width: | Height: | Size: 981 B |
BIN
plug-ins/ahoge/2025/icons/ahoge_extra.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_fix.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_info.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
plug-ins/ahoge/2025/icons/ahoge_misc.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
plug-ins/ahoge/2025/icons/nurbopusNode.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
plug-ins/ahoge/2025/icons/out_ahogeShape.png
Normal file
|
After Width: | Height: | Size: 1002 B |
BIN
plug-ins/ahoge/2025/icons/out_nurbopusNode.png
Normal file
|
After Width: | Height: | Size: 703 B |
BIN
plug-ins/ahoge/2025/mtoa/ahogeTranslator.dll
Normal file
BIN
plug-ins/ahoge/2025/plugins/ahoge.mll
Normal file
103
plug-ins/ahoge/2025/scripts/AEahogeShapeTemplate.mel
Normal file
@@ -0,0 +1,103 @@
|
||||
global proc AEahogeShapeTemplate(string $nodeName)
|
||||
{
|
||||
editorTemplate -beginScrollLayout;
|
||||
|
||||
editorTemplate -beginLayout "Seed" -collapse true;
|
||||
editorTemplate -addControl "seed";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Color" -collapse false;
|
||||
AEaddRampControl($nodeName + ".colorRamp");
|
||||
|
||||
editorTemplate -beginLayout "Mutant Color" -collapse true;
|
||||
editorTemplate -l "Mutant Color" -addControl "mutantColor";
|
||||
editorTemplate -l "Mutant Percent" -addControl "mutantPercent";
|
||||
editorTemplate -l "Mutant Fuzziness" -addControl "mutantFuzziness";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Randomize Color" -collapse true;
|
||||
editorTemplate -l "Randomize Color" -addControl "randomizeColor";
|
||||
editorTemplate -l "Randomize Saturation" -addControl "randomizeSaturation";
|
||||
editorTemplate -l "Randomize Value" -addControl "randomizeValue";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Absolute Length" -collapse true;
|
||||
editorTemplate -l "Use Absolute Length" -addControl "useAbsoluteLength";
|
||||
editorTemplate -l "Absolute Length" -addControl "absoluteLength";
|
||||
editorTemplate -endLayout;
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "General" -collapse false;
|
||||
editorTemplate -l "Segments" -addControl "numSegments";
|
||||
editorTemplate -l "Curves" -addControl "numCurves";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Width" -collapse false;
|
||||
editorTemplate -l "Width" -addControl "width";
|
||||
AEaddRampControl($nodeName + ".widthRamp");
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Noise" -collapse false;
|
||||
editorTemplate -l "Random Placement" -addControl "randomPlacement";
|
||||
editorTemplate -l "Random Placement Type" -addControl "randomPlacementType";
|
||||
editorTemplate -l "Noise" -addControl "noise";
|
||||
editorTemplate -l "Frequency" -addControl "frequency";
|
||||
editorTemplate -l "Octaves" -addControl "octaves";
|
||||
editorTemplate -l "Persistence" -addControl "persistence";
|
||||
AEaddRampControl($nodeName + ".noiseRamp");
|
||||
editorTemplate -beginLayout "Randomize Frequency" -collapse true;
|
||||
editorTemplate -l "Enable Randomize Frequency" -addControl "enableRandomizeFrequency";
|
||||
editorTemplate -l "Randomize Frequency Min" -addControl "randomizeFrequencyMin";
|
||||
editorTemplate -l "Randomize Frequency Max" -addControl "randomizeFrequencyMax";
|
||||
AEaddRampControl($nodeName + ".randomizeFrequencyDistribution");
|
||||
editorTemplate -endLayout;
|
||||
editorTemplate -beginLayout "Randomize Noise" -collapse true;
|
||||
editorTemplate -l "Randomize Noise" -addControl "randomizeNoise";
|
||||
AEaddRampControl($nodeName + ".randomizeNoiseDistribution");
|
||||
editorTemplate -endLayout;
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Cut" -collapse false;
|
||||
editorTemplate -l "Cut" -addControl "cut";
|
||||
editorTemplate -l "Compress Noise Frequency" -addControl "compressNoiseFrequency";
|
||||
AEaddRampControl($nodeName + ".cutDistribution");
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Spray" -collapse false;
|
||||
editorTemplate -l "Fill" -addControl "fill";
|
||||
editorTemplate -l "Shift" -addControl "shift";
|
||||
editorTemplate -l "Spray Along Normal" -addControl "sprayAlongNormal";
|
||||
editorTemplate -l "Spray" -addControl "spray";
|
||||
AEaddRampControl($nodeName + ".sprayRamp");
|
||||
AEaddRampControl($nodeName + ".sprayDistribution");
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Multistrand" -collapse false;
|
||||
editorTemplate -l "Multistrand" -addControl "multistrand";
|
||||
editorTemplate -l "Multistrand Percent" -addControl "multistrandPercent";
|
||||
editorTemplate -l "Multistrand Randomize" -addControl "multistrandRandomize";
|
||||
editorTemplate -l "Multistrand Randomize Tip" -addControl "multistrandRandomizeTip";
|
||||
editorTemplate -l "Multistrand Twist" -addControl "multistrandTwist";
|
||||
editorTemplate -l "Multistrand Twist Randomize" -addControl "multistrandTwistRandomize";
|
||||
editorTemplate -l "Multistrand Spray" -addControl "multistrandSpray";
|
||||
editorTemplate -l "Multistrand Randomize Spray" -addControl "multistrandRandomizeSpray";
|
||||
AEaddRampControl($nodeName + ".multistrandSprayRamp");
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Arnold" -collapse true;
|
||||
editorTemplate -l "Mode" -addControl "aiMode";
|
||||
editorTemplate -l "Min Pixel Width" -addControl "aiMinPixelWidth";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Viewport" -collapse true;
|
||||
editorTemplate -l "Display Mode" -addControl "displayMode";
|
||||
editorTemplate -l "Preview Percent" -addControl "previewPercent";
|
||||
editorTemplate -l "Preview Sides" -addControl "previewSides";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
AEsurfaceShapeTemplate $nodeName;
|
||||
|
||||
editorTemplate -addExtraControls;
|
||||
|
||||
editorTemplate -endScrollLayout;
|
||||
}
|
||||
32
plug-ins/ahoge/2025/scripts/AEnurbopusNodeTemplate.mel
Normal file
@@ -0,0 +1,32 @@
|
||||
global proc AEnurbopusNodeTemplate(string $nodeName)
|
||||
{
|
||||
editorTemplate -beginScrollLayout;
|
||||
|
||||
editorTemplate -beginLayout "General" -collapse false;
|
||||
editorTemplate -l "Up Vector" -addControl "upVector";
|
||||
editorTemplate -l "Method" -addControl "method";
|
||||
editorTemplate -l "Shape" -addControl "shape";
|
||||
editorTemplate -l "U Segments" -addControl "uSegments";
|
||||
editorTemplate -l "V Segments" -addControl "vSegments";
|
||||
editorTemplate -l "Segments Power" -addControl "segmentsPower";
|
||||
editorTemplate -l "Radius" -addControl "radius";
|
||||
editorTemplate -l "Scale Y" -addControl "scaleY";
|
||||
editorTemplate -l "Rotate" -addControl "rotate";
|
||||
editorTemplate -l "twist" -addControl "twist";
|
||||
AEaddRampControl($nodeName + ".ramp");
|
||||
editorTemplate -endLayout;
|
||||
|
||||
editorTemplate -beginLayout "Orientation" -collapse false;
|
||||
editorTemplate -l "Use Mesh Normal" -addControl "useMeshNormal";
|
||||
editorTemplate -l "Orient Method" -addControl "orientMethod";
|
||||
editorTemplate -l "Orient" -addControl "orient";
|
||||
editorTemplate -l "Orient Point" -addControl "orientPoint";
|
||||
editorTemplate -l "Orient Segment" -addControl "orientSegment";
|
||||
editorTemplate -endLayout;
|
||||
|
||||
AEdependNodeTemplate $nodeName;
|
||||
|
||||
editorTemplate -addExtraControls;
|
||||
|
||||
editorTemplate -endScrollLayout;
|
||||
}
|
||||
484
plug-ins/ahoge/2025/scripts/ahogeTools.mel
Normal file
@@ -0,0 +1,484 @@
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
489
plug-ins/ahoge/2025/scripts/ahoge_ui.py
Normal file
@@ -0,0 +1,489 @@
|
||||
import maya.cmds as cmds
|
||||
|
||||
if cmds.about(version=True) == "2025":
|
||||
from PySide6 import QtWidgets, QtGui
|
||||
import shiboken6 as shiboken
|
||||
else:
|
||||
from PySide2 import QtWidgets, QtGui
|
||||
import shiboken2 as shiboken
|
||||
|
||||
import maya.OpenMayaUI as omui
|
||||
from enum import Enum
|
||||
import random
|
||||
import os
|
||||
import pathlib
|
||||
from datetime import datetime
|
||||
import time
|
||||
|
||||
|
||||
def get_scaling_ratio():
|
||||
screen = QtGui.QGuiApplication.primaryScreen()
|
||||
return screen.logicalDotsPerInch() / 96.0
|
||||
|
||||
scaling_ratio = get_scaling_ratio()
|
||||
|
||||
def maya_main_window():
|
||||
main_window_pointer = omui.MQtUtil.mainWindow()
|
||||
return shiboken.wrapInstance(int(main_window_pointer), QtWidgets.QWidget)
|
||||
|
||||
class OptionType(Enum):
|
||||
Unknown = 1
|
||||
Bool = 2
|
||||
Int = 3
|
||||
Float = 4
|
||||
Option = 5
|
||||
File = 6
|
||||
|
||||
class Option:
|
||||
|
||||
option_type = OptionType.Unknown
|
||||
option_name = None
|
||||
default = None
|
||||
setting = None
|
||||
widget = None
|
||||
|
||||
def __init__(self, option_name, option_type, default, setting, meta=None):
|
||||
self.option_name = option_name
|
||||
self.option_type = option_type
|
||||
self.default = default
|
||||
self.setting = setting
|
||||
self.meta = meta
|
||||
|
||||
def make_widget(self, form_layout):
|
||||
if self.option_type == OptionType.Bool:
|
||||
self.widget = QtWidgets.QCheckBox()
|
||||
self.widget.setChecked(self.default)
|
||||
form_layout.addRow(self.option_name + ":", self.widget)
|
||||
elif self.option_type == OptionType.Int:
|
||||
self.widget = QtWidgets.QSpinBox()
|
||||
self.widget.setFixedWidth(70 * scaling_ratio)
|
||||
self.widget.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
|
||||
if self.meta:
|
||||
if "min" in self.meta:
|
||||
self.widget.setMinimum(self.meta["min"])
|
||||
if "max" in self.meta:
|
||||
self.widget.setMaximum(self.meta["max"])
|
||||
self.widget.setValue(self.default)
|
||||
form_layout.addRow(self.option_name + ":", self.widget)
|
||||
elif self.option_type == OptionType.Float:
|
||||
self.widget = QtWidgets.QDoubleSpinBox()
|
||||
self.widget.setDecimals(4)
|
||||
self.widget.setSingleStep(0.01)
|
||||
self.widget.setFixedWidth(70 * scaling_ratio)
|
||||
self.widget.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
|
||||
if self.meta:
|
||||
if "min" in self.meta:
|
||||
self.widget.setMinimum(self.meta["min"])
|
||||
if "max" in self.meta:
|
||||
self.widget.setMaximum(self.meta["max"])
|
||||
self.widget.setValue(self.default)
|
||||
form_layout.addRow(self.option_name + ":", self.widget)
|
||||
elif self.option_type == OptionType.Option:
|
||||
self.widget = QtWidgets.QComboBox()
|
||||
if self.meta:
|
||||
if "options" in self.meta:
|
||||
for option in self.meta["options"]:
|
||||
self.widget.addItem(option[1], option[0])
|
||||
form_layout.addRow(self.option_name + ":", self.widget)
|
||||
index = self.widget.findData(self.default)
|
||||
self.widget.setCurrentIndex(index)
|
||||
elif self.option_type == OptionType.File:
|
||||
self.widget = QtWidgets.QLineEdit()
|
||||
widget_layout = QtWidgets.QHBoxLayout()
|
||||
widget_layout.setContentsMargins(0, 0, 0, 0)
|
||||
browse_button = QtWidgets.QPushButton("Browse")
|
||||
|
||||
def browse_action():
|
||||
path = self.widget.text()
|
||||
file_filter = ""
|
||||
if self.meta:
|
||||
if "fileFilter" in self.meta:
|
||||
file_filter = self.meta["fileFilter"]
|
||||
result = cmds.fileDialog2(dir=path, fileFilter=file_filter, dialogStyle=2)
|
||||
if result:
|
||||
self.widget.setText(result[0])
|
||||
|
||||
browse_button.clicked.connect(browse_action)
|
||||
|
||||
widget_layout.addWidget(self.widget)
|
||||
widget_layout.addWidget(browse_button)
|
||||
form_layout.addRow(self.option_name + ":", widget_layout)
|
||||
self.widget.setText(self.default)
|
||||
|
||||
def load(self):
|
||||
if not self.widget:
|
||||
return
|
||||
if self.option_type == OptionType.Bool:
|
||||
if cmds.optionVar(exists=self.setting):
|
||||
value = bool(cmds.optionVar(q=self.setting))
|
||||
self.widget.setChecked(value)
|
||||
elif self.option_type == OptionType.Int:
|
||||
if cmds.optionVar(exists=self.setting):
|
||||
value = cmds.optionVar(q=self.setting)
|
||||
self.widget.setValue(value)
|
||||
elif self.option_type == OptionType.Float:
|
||||
if cmds.optionVar(exists=self.setting):
|
||||
value = cmds.optionVar(q=self.setting)
|
||||
self.widget.setValue(value)
|
||||
elif self.option_type == OptionType.Option:
|
||||
if cmds.optionVar(exists=self.setting):
|
||||
value = cmds.optionVar(q=self.setting)
|
||||
index = self.widget.findData(value)
|
||||
self.widget.setCurrentIndex(index)
|
||||
elif self.option_type == OptionType.File:
|
||||
if cmds.optionVar(exists=self.setting):
|
||||
value = cmds.optionVar(q=self.setting)
|
||||
self.widget.setText(value)
|
||||
|
||||
def save(self):
|
||||
if not self.widget:
|
||||
return
|
||||
if self.option_type == OptionType.Bool:
|
||||
if self.widget.isChecked():
|
||||
cmds.optionVar(iv=(self.setting, 1))
|
||||
else:
|
||||
cmds.optionVar(iv=(self.setting, 0))
|
||||
elif self.option_type == OptionType.Int:
|
||||
cmds.optionVar(iv=(self.setting, self.widget.value()))
|
||||
elif self.option_type == OptionType.Float:
|
||||
cmds.optionVar(fv=(self.setting, self.widget.value()))
|
||||
elif self.option_type == OptionType.Option:
|
||||
cmds.optionVar(iv=(self.setting, self.widget.currentData()))
|
||||
elif self.option_type == OptionType.File:
|
||||
cmds.optionVar(sv=(self.setting, self.widget.text()))
|
||||
|
||||
def reset(self):
|
||||
if not self.widget:
|
||||
return
|
||||
if self.option_type == OptionType.Bool:
|
||||
self.widget.setChecked(self.default)
|
||||
if self.default:
|
||||
cmds.optionVar(iv=(self.setting, 1))
|
||||
else:
|
||||
cmds.optionVar(iv=(self.setting, 0))
|
||||
elif self.option_type == OptionType.Int:
|
||||
self.widget.setValue(self.default)
|
||||
cmds.optionVar(iv=(self.setting, self.default))
|
||||
elif self.option_type == OptionType.Float:
|
||||
self.widget.setValue(self.default)
|
||||
cmds.optionVar(fv=(self.setting, self.default))
|
||||
elif self.option_type == OptionType.Option:
|
||||
index = self.widget.findData(self.default)
|
||||
self.widget.setCurrentIndex(index)
|
||||
cmds.optionVar(iv=(self.setting, self.default))
|
||||
elif self.option_type == OptionType.File:
|
||||
self.widget.setText(self.default)
|
||||
cmds.optionVar(sv=(self.setting, self.default))
|
||||
|
||||
class OptionsDialogType(Enum):
|
||||
Create = 1
|
||||
Export = 2
|
||||
|
||||
class OptionsDialog(QtWidgets.QDialog):
|
||||
|
||||
def __init__(self, options_dialog_type, title, command, options, parent=None):
|
||||
super(OptionsDialog, self).__init__(parent)
|
||||
|
||||
self.setWindowTitle(title)
|
||||
|
||||
self.options_dialog_type = options_dialog_type
|
||||
self.command = command
|
||||
self.options = options
|
||||
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.setLayout(layout)
|
||||
|
||||
menu_bar = QtWidgets.QMenuBar()
|
||||
edit_menu = menu_bar.addMenu("Edit")
|
||||
edit_menu.addAction("Save Settings", self.save)
|
||||
edit_menu.addAction("Reset Settings", self.reset)
|
||||
|
||||
if self.options_dialog_type == OptionsDialogType.Export:
|
||||
edit_menu.addSeparator()
|
||||
edit_menu.addAction("Clear Log", self.clear_log)
|
||||
|
||||
layout.addWidget(menu_bar)
|
||||
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
form_layout_margins = 8 * scaling_ratio
|
||||
form_layout.setContentsMargins(
|
||||
form_layout_margins, form_layout_margins, form_layout_margins, form_layout_margins)
|
||||
|
||||
for option in self.options:
|
||||
option.make_widget(form_layout)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
|
||||
if options_dialog_type == OptionsDialogType.Create:
|
||||
layout.addStretch()
|
||||
|
||||
buttons_layout = QtWidgets.QHBoxLayout()
|
||||
layout.addLayout(buttons_layout)
|
||||
buttons_layout_margins = 4 * scaling_ratio
|
||||
buttons_layout.setContentsMargins(
|
||||
buttons_layout_margins, buttons_layout_margins, buttons_layout_margins, buttons_layout_margins)
|
||||
buttons_layout.setSpacing(4)
|
||||
|
||||
if options_dialog_type == OptionsDialogType.Create:
|
||||
create_button = QtWidgets.QPushButton("Create")
|
||||
apply_button = QtWidgets.QPushButton("Apply")
|
||||
close_button = QtWidgets.QPushButton("Close")
|
||||
|
||||
create_button.clicked.connect(self.create)
|
||||
apply_button.clicked.connect(self.apply)
|
||||
close_button.clicked.connect(self.close)
|
||||
|
||||
buttons_layout.addWidget(create_button)
|
||||
buttons_layout.addWidget(apply_button)
|
||||
buttons_layout.addWidget(close_button)
|
||||
elif options_dialog_type == OptionsDialogType.Export:
|
||||
self.log = QtWidgets.QTextEdit()
|
||||
#self.log.setFixedHeight(80)
|
||||
self.log.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
|
||||
self.log.setReadOnly(True)
|
||||
form_layout.addRow("Log:", self.log)
|
||||
|
||||
export_button = QtWidgets.QPushButton("Export")
|
||||
close_button = QtWidgets.QPushButton("Close")
|
||||
|
||||
export_button.clicked.connect(self.apply)
|
||||
close_button.clicked.connect(self.close)
|
||||
|
||||
buttons_layout.addStretch()
|
||||
buttons_layout.addWidget(export_button)
|
||||
buttons_layout.addWidget(close_button)
|
||||
|
||||
self.load()
|
||||
self.show()
|
||||
|
||||
def load(self):
|
||||
for option in self.options:
|
||||
option.load()
|
||||
|
||||
def save(self):
|
||||
for option in self.options:
|
||||
option.save()
|
||||
|
||||
def reset(self):
|
||||
for option in self.options:
|
||||
option.reset()
|
||||
|
||||
def create(self):
|
||||
self.save()
|
||||
self.command()
|
||||
self.close()
|
||||
|
||||
def apply(self):
|
||||
self.save()
|
||||
if self.options_dialog_type == OptionsDialogType.Export:
|
||||
start_time = time.time()
|
||||
start_date = datetime.now()
|
||||
self.log.moveCursor(QtGui.QTextCursor.End)
|
||||
self.log.append("<font color=grey>Export started</font> " + str(start_date))
|
||||
try:
|
||||
self.command()
|
||||
end_time = time.time()
|
||||
end_date = datetime.now()
|
||||
self.log.moveCursor(QtGui.QTextCursor.End)
|
||||
self.log.append("<font color=grey>Export ended</font> " + str(end_date))
|
||||
self.log.append("<font color=grey>Export took</font> %.4f <font color=grey>seconds</font>" % (end_time - start_time))
|
||||
self.log.append("<font color=green>Done</font>")
|
||||
except Exception as e:
|
||||
self.log.moveCursor(QtGui.QTextCursor.End)
|
||||
self.log.append("<font color=orange>%s</font>" % e)
|
||||
self.log.append("<font color=red>Failure</font>")
|
||||
else:
|
||||
self.command()
|
||||
|
||||
def activate(self):
|
||||
self.load()
|
||||
self.show()
|
||||
self.activateWindow()
|
||||
|
||||
def clear_log(self):
|
||||
self.log.clear()
|
||||
|
||||
def get_value(setting):
|
||||
if cmds.optionVar(exists=setting[1]):
|
||||
return cmds.optionVar(q=setting[1])
|
||||
return setting[0]
|
||||
|
||||
create_ahoge_window = None
|
||||
|
||||
create_ahoge_randomize_seed = [True, "ahoge_randomize_seed"]
|
||||
create_ahoge_swap_uv = [True, "ahoge_randomize_swap_uv"]
|
||||
create_ahoge_segments = [16, "ahoge_segments"]
|
||||
create_ahoge_number_of_curves = [10, "ahoge_number_of_curves"]
|
||||
create_ahoge_width = [0.01, "ahoge_width"]
|
||||
|
||||
def create_ahoge():
|
||||
cmds.undoInfo(chunkName="create_ahoge", openChunk=True)
|
||||
try:
|
||||
randomize_seed = get_value(create_ahoge_randomize_seed)
|
||||
swap_uv = get_value(create_ahoge_swap_uv)
|
||||
segments = get_value(create_ahoge_segments)
|
||||
number_of_curves = get_value(create_ahoge_number_of_curves)
|
||||
width = get_value(create_ahoge_width)
|
||||
|
||||
surfaces = cmds.ls(sl=True, dag=True, type="nurbsSurface")
|
||||
ahoge_shape = cmds.createNode("ahogeShape")
|
||||
|
||||
if randomize_seed:
|
||||
cmds.setAttr(ahoge_shape + ".seed", random.randint(0, 10000))
|
||||
|
||||
cmds.setAttr(ahoge_shape + ".numSegments", segments)
|
||||
cmds.setAttr(ahoge_shape + ".numCurves", number_of_curves)
|
||||
cmds.setAttr(ahoge_shape + ".width", width)
|
||||
|
||||
for index, surface in enumerate(surfaces):
|
||||
if swap_uv and cmds.getAttr(surface + ".fu") == 0 and cmds.getAttr(surface + ".fv") == 2:
|
||||
cmds.warning(surface + " swapping UV")
|
||||
cmds.reverseSurface(surface, d=3, ch=1, rpo=1)
|
||||
cmds.reverseSurface(surface, d=0, ch=1, rpo=1)
|
||||
cmds.connectAttr(surface + ".worldSpace[0]", ahoge_shape + ".inputSurfaces[" + str(index) + "]")
|
||||
finally:
|
||||
cmds.undoInfo(closeChunk=True)
|
||||
|
||||
def create_ahoge_options():
|
||||
global create_ahoge_window
|
||||
if not create_ahoge_window:
|
||||
title = "Create Ahoge Options"
|
||||
options = []
|
||||
options.append(Option("Randomize Seed", OptionType.Bool, *create_ahoge_randomize_seed))
|
||||
options.append(Option("Swap UV", OptionType.Bool, *create_ahoge_swap_uv))
|
||||
options.append(Option("Segments", OptionType.Int, *create_ahoge_segments, {"min": 1, "max": 1000000}))
|
||||
options.append(Option("Number of Curves", OptionType.Int, *create_ahoge_number_of_curves, {"min": 1, "max": 1000000}))
|
||||
options.append(Option("Width", OptionType.Float, *create_ahoge_width, {"min": 0.0001, "max": 1000000.0}))
|
||||
|
||||
create_ahoge_window = OptionsDialog(OptionsDialogType.Create, title, create_ahoge, options, maya_main_window())
|
||||
else:
|
||||
create_ahoge_window.activate()
|
||||
|
||||
create_nurbopus_window = None
|
||||
|
||||
create_nurbopus_method = [1, "ahoge_nurbopus_method"]
|
||||
create_nurbopus_shape = [0, "ahoge_nurbopus_shape"]
|
||||
create_nurbopus_useg = [4, "ahoge_nurbopus_useg"]
|
||||
create_nurbopus_vseg = [8, "ahoge_nurbopus_vseg"]
|
||||
|
||||
def create_nurbopus():
|
||||
cmds.undoInfo(chunkName="create_nurbopus", openChunk=True)
|
||||
try:
|
||||
method = get_value(create_nurbopus_method)
|
||||
shape = get_value(create_nurbopus_shape)
|
||||
useg = get_value(create_nurbopus_useg)
|
||||
vseg = get_value(create_nurbopus_vseg)
|
||||
|
||||
curves = cmds.ls(sl=True, dag=True, type="nurbsCurve")
|
||||
if not curves:
|
||||
cmds.error("No curves selected")
|
||||
meshes = cmds.ls(sl=True, dag=True, type="mesh")
|
||||
|
||||
nurbopus = cmds.createNode("nurbopusNode")
|
||||
|
||||
cmds.setAttr(nurbopus + ".method", method)
|
||||
cmds.setAttr(nurbopus + ".shape", shape)
|
||||
cmds.setAttr(nurbopus + ".uSegments", useg)
|
||||
cmds.setAttr(nurbopus + ".vSegments", vseg)
|
||||
|
||||
for index, curve in enumerate(curves):
|
||||
cmds.connectAttr(curve + ".worldSpace[0]", nurbopus + ".inputCurves[" + str(index) + "]")
|
||||
surface = cmds.createNode("nurbsSurface")
|
||||
|
||||
cmds.connectAttr(nurbopus + ".outputSurfaces[" + str(index) + "]", surface + ".create")
|
||||
cmds.hyperShade(surface, assign="initialShadingGroup")
|
||||
|
||||
if meshes:
|
||||
cmds.connectAttr(meshes[0] + ".worldMesh[0]", nurbopus + ".inputMesh")
|
||||
|
||||
cmds.select(nurbopus)
|
||||
|
||||
finally:
|
||||
cmds.undoInfo(closeChunk=True)
|
||||
|
||||
def create_nurbopus_options():
|
||||
global create_nurbopus_window
|
||||
if not create_nurbopus_window:
|
||||
title = "Create Nurbopus Options"
|
||||
options = []
|
||||
options.append(Option("Method", OptionType.Option, *create_nurbopus_method, {"options": [[0, "Up Vector"], [1, "Untwist"]]}))
|
||||
options.append(Option("Shape", OptionType.Option, *create_nurbopus_shape, {"options": [[0, "circle"], [1, "line"]]}))
|
||||
options.append(Option("U Segments", OptionType.Int, *create_nurbopus_useg, {"min": 1, "max": 1000000}))
|
||||
options.append(Option("V Segments", OptionType.Int, *create_nurbopus_vseg, {"min": 1, "max": 1000000}))
|
||||
|
||||
create_nurbopus_window = OptionsDialog(OptionsDialogType.Create, title, create_nurbopus, options, maya_main_window())
|
||||
else:
|
||||
create_nurbopus_window.activate()
|
||||
|
||||
export_alembic_window = None
|
||||
|
||||
abc_path = pathlib.Path(os.environ["MAYA_APP_DIR"])
|
||||
abc_path = abc_path / "projects" / "default" / "data" / "test.abc"
|
||||
export_alembic_path = [str(abc_path), "ahoge_export_alembic_path"]
|
||||
|
||||
export_alembic_mode = [0, "ahoge_export_alembic_mode"]
|
||||
export_alembic_time_range = [0, "ahoge_export_alembic_time_range"]
|
||||
export_alembic_start = [1, "ahoge_export_alembic_start"]
|
||||
export_alembic_end = [24, "ahoge_export_alembic_end"]
|
||||
export_alembic_relative_sample = [False, "ahoge_export_alembic_relative_sample"]
|
||||
export_alembic_low = [-0.2, "ahoge_export_alembic_low"]
|
||||
export_alembic_high = [0.2, "ahoge_export_alembic_high"]
|
||||
|
||||
def export_alembic():
|
||||
alembic_mode = get_value(export_alembic_mode)
|
||||
alembic_time_range = get_value(export_alembic_time_range)
|
||||
alembic_path = get_value(export_alembic_path)
|
||||
|
||||
start = get_value(export_alembic_start)
|
||||
end = get_value(export_alembic_end)
|
||||
|
||||
relative_sample = get_value(export_alembic_relative_sample)
|
||||
low = get_value(export_alembic_low)
|
||||
high = get_value(export_alembic_high)
|
||||
|
||||
export_mode="default"
|
||||
if alembic_mode == 1:
|
||||
export_mode = "unreal"
|
||||
elif alembic_mode == 2:
|
||||
export_mode = "marmoset"
|
||||
|
||||
extra = ""
|
||||
|
||||
time_range = "current_frame"
|
||||
if alembic_time_range == 1:
|
||||
time_range = "time_slider"
|
||||
elif alembic_time_range == 2:
|
||||
time_range = "start_end"
|
||||
extra += " -startEnd %d %d" % (start, end)
|
||||
|
||||
if relative_sample:
|
||||
extra += " -relativeSample true -lowHigh %f %f" % (low, high)
|
||||
|
||||
print("ahogeCmd -e \"%s\" -exportMode \"%s\" -timeRange \"%s\"%s;" %
|
||||
(alembic_path.replace("\\", "/"), export_mode, time_range, extra))
|
||||
cmds.ahogeCmd(e=alembic_path,
|
||||
exportMode=export_mode,
|
||||
timeRange=time_range,
|
||||
startEnd=(start, end),
|
||||
relativeSample=relative_sample,
|
||||
lowHigh=(low, high))
|
||||
|
||||
def export_alembic_options():
|
||||
global export_alembic_window
|
||||
if not export_alembic_window:
|
||||
title = "Ahoge Export: Alembic"
|
||||
options = []
|
||||
options.append(Option("Path", OptionType.File, *export_alembic_path, {"fileFilter": "*.abc"}))
|
||||
options.append(Option("Mode", OptionType.Option, *export_alembic_mode, {"options": [[0, "Default"], [1, "Unreal"], [2, "Marmoset"]]}))
|
||||
options.append(Option("Time Range", OptionType.Option, *export_alembic_time_range, {"options": [[0, "Current Frame"], [1, "Time Slider"], [2, "Start/End"]]}))
|
||||
options.append(Option("Start Frame", OptionType.Int, *export_alembic_start, {"min": -1000000, "max": 1000000}))
|
||||
options.append(Option("End Frame", OptionType.Int, *export_alembic_end, {"min": -1000000, "max": 1000000}))
|
||||
options.append(Option("Relative Sample", OptionType.Bool, *export_alembic_relative_sample))
|
||||
options.append(Option("Low", OptionType.Float, *export_alembic_low, {"min": -1.0, "max": 0.0}))
|
||||
options.append(Option("High", OptionType.Float, *export_alembic_high, {"min": 0.0, "max": 1.0}))
|
||||
|
||||
export_alembic_window = OptionsDialog(OptionsDialogType.Export, title, export_alembic, options, maya_main_window())
|
||||
else:
|
||||
export_alembic_window.activate()
|
||||