< |
////////////
//
// Script: senReuseTriangles 0.1.4
// Updated: 17 May 2008
// Compatibility: Maya 8 and higher
// Probably works with earlier versions, too.
//
//
// Written by Sven-Erik Neve
// Website and contact info: www.seneve.de
// Bugs, comments, questions or suggestions? Get in touch!
//
//
// Usage:
// Use the senReuseTriangles command to start the script.
// Select at least one for example polygon object, choose
// whether to enable or to disable reuseTriangles and
// confirm your choice.
//
//
// Installation:
// Copy this source code within a MEL file to one of your
// scripts folders, for example on Windows XP 32-bit to the
// folder \My Documents\maya\<version>\scripts. Start Maya
// or (if it is running) use the rehash command to make Maya
// aware of the newly copied script. Execute the script with
// the senReuseTriangles command. In the script's ZIP archive
// you'll also find an XPM icon that you can copy for example
// to \My Documents\maya\<version>\prefs\icons.
//
//
// Purpose:
// By default Maya reevaluates triangles on the fly which
// may cause textures to flicker when you animate an object.
// The reuseTriangles attribute controls this. All mesh nodes
// have it. This script allows you to enable reuseTriangles
// so that Maya literally reuses the triangle positions from
// your object's bind pose instead of recalculating them
// on the fly. This in turn stops textures from flickering.
//
////////////
// Set version and date of last modification
proc string[] versionInfo() {
string $version = "0.1.4";
string $modDate = "17 May 2008";
string $scriptInfo[] = {$version, $modDate};
return $scriptInfo;
}
// Run this when the window is about to be closed, clean up
global proc senReuseTrianglesCloseWindow(string $window) {
deleteUI $window;
// If user wants to reset settings, do it
if (`optionVar -ex senReuseTrianglesReset`) {
if (`windowPref -ex $window`) windowPref -r $window;
optionVar -rm senReuseTrianglesReset;
if (`optionVar -ex senReuseTrianglesCurrentValue`) {
optionVar -rm senReuseTrianglesCurrentValue;
}
if (`optionVar -ex senReuseTrianglesSavedValue`) {
optionVar -rm senReuseTrianglesSavedValue;
}
}
}
// Count selected objects in total and mesh nodes in selection
proc int[] countObjs() {
string $meshes[] = sort(`ls -sl -dag -lf -typ mesh`);
int $counter[] = {(size(`ls -sl`)), (size($meshes))};
return $counter;
}
// On window creation, determine which radio button shall be selected
proc int getSavedValue() {
int $rtriState = 1;
if (`optionVar -ex senReuseTrianglesSavedValue`) {
$rtriState = `optionVar -q senReuseTrianglesSavedValue`;
}
optionVar -iv senReuseTrianglesCurrentValue $rtriState;
return $rtriState;
}
// On selection change, determine which radio button is _now_ selected
global proc int senReuseTrianglesGetCurrentValue() {
int $rtriState = 1;
if (`optionVar -ex senReuseTrianglesCurrentValue`) {
$rtriState = `optionVar -q senReuseTrianglesCurrentValue`;
}
return $rtriState;
}
// When another radio button is selected save which one it is
global proc senReuseTrianglesSetRadioBtnState(string $rtriRadioBtns) {
int $rtriState = (2 - `radioButtonGrp -q -sl $rtriRadioBtns`);
optionVar -iv senReuseTrianglesCurrentValue $rtriState;
}
// Create info texts to inform user of script status
proc string[] createTexts(int $counter[]) {
string $report;
string $instruct;
float $statusColor[];
string $texts[];
if (!$counter[0]) {
$report = "Nothing selected.\n";
$instruct = "Select at least one for example polygon object.";
$statusColor = {0.9, 0.15, 0.0};
}
else if ($counter[0] && !$counter[1]) {
$report = "No mesh nodes in selection.\n";
$instruct = "Select at least one for example polygon object.";
$statusColor = {1.0, 0.7, 0.1};
}
else {
$report = "You're good to go.\n";
$instruct = "Enable reuseTriangles to make sure " +
"textures don't flicker.";
$statusColor = {0.27, 0.8, 0.0};
}
$texts = {$report, $instruct, $statusColor[0], $statusColor[1], $statusColor[2]};
return $texts;
}
// Save settings
global proc senReuseTrianglesSaveSettings(string $rtriRadioBtns) {
int $rtriState = (2 - `radioButtonGrp -q -sl $rtriRadioBtns`);
optionVar -iv senReuseTrianglesCurrentValue $rtriState;
optionVar -iv senReuseTrianglesSavedValue $rtriState;
}
// Reset settings; actual reset occurs when window closes
global proc senReuseTrianglesResetSettings(string $rtriRadioBtns) {
optionVar -iv senReuseTrianglesSavedValue 1;
radioButtonGrp -e -sl 1 $rtriRadioBtns;
optionVar -iv senReuseTrianglesReset 1;
}
// Get length of Help window just before the user changes something
global proc int senReuseTrianglesGetHelpMenuLen(string $helpMenu) {
int $helpMenuLen = `window -q -h $helpMenu`;
return $helpMenuLen;
}
// Change length of Help window when user opens and closes frameLayouts
global proc senReuseTrianglesHelpMenuChangeLen(int $frame, int $incLen, int $helpMenuLen, string $helpMenu) {
if ($incLen) {
if ($frame) window -e -h ($helpMenuLen + 110) $helpMenu;
else window -e -h ($helpMenuLen + 200) $helpMenu;
}
else {
if ($frame) window -e -h ($helpMenuLen - 110) $helpMenu;
else window -e -h ($helpMenuLen - 200) $helpMenu;
}
}
// Create Help menu
global proc senReuseTrianglesHelpMenu(string $script) {
int $helpMenuLen = 350;
string $helpMenu = ($script + "HelpWindow");
string $versionInfo[] = versionInfo();
// If Help window already exists delete it
if (`window -ex $helpMenu`) deleteUI $helpMenu;
if (`windowPref -ex $helpMenu`) windowPref -r $helpMenu;
window -t ($script + " Help") -mb true -wh 400 $helpMenuLen $helpMenu;
showWindow $helpMenu;
// Create formLayout to accommodate four frames
string $helpMenuFrame = `formLayout "helpMenuFrame"`;
// "About" frame
string $helpAbout = `frameLayout
-l ("About " + $script + "\n") -bs "etchedIn"
-la center -li 5 -mw 10 -mh 10 "helpAboutHeadlineFrame"`;
string $helpAboutText = `text -l ("Version: " + $versionInfo[0] + "\n" +
"Updated: " + $versionInfo[1] + "\n" +
"Compatibility: Maya 8 and higher\n" +
"Probably works with earlier versions, too.\n\n" +
"Written by Sven-Erik Neve\n" +
"Website and contact info: www.seneve.de\n" +
"Bugs, comments, questions or suggestions? Get in touch!") "helpAboutText"`;
setParent ..;
// "Usage (summary)" frame
string $helpUsageShort = `frameLayout
-l ("Usage (summary)") -bs "etchedIn"
-la center -li 5 -mw 10 -mh 10 "helpUsageShortFrame"`;
string $helpUsageShortText = `text -l ("Select at least one for example polygon object, choose whether\n" +
"to enable or to disable reuseTriangles and confirm your choice.") "helpUsageShortText"`;
setParent ..;
// "Usage (in-depth)" frame
string $helpUsageLong = `frameLayout
-l ("Usage (in-depth)") -bs "etchedIn" -cll true -cl true
-pec ("senReuseTrianglesHelpMenuChangeLen(0, 1, senReuseTrianglesGetHelpMenuLen(\"" + $helpMenu + "\"), \"" + $helpMenu + "\")")
-pcc ("senReuseTrianglesHelpMenuChangeLen(0, 0, senReuseTrianglesGetHelpMenuLen(\"" + $helpMenu + "\"), \"" + $helpMenu + "\")")
-la center -li 5 -mw 10 -mh 10 "helpUsageLongFrame"`;
string $helpUsageLongText = `text -l ("Select an object that contains a mesh node, for example select a\n" +
"polygon object. The script's Status will inform you at all times whether\n" +
"your selection contains a mesh node or not. Once you have something\n" +
"selected that contains at least one mesh node the script is ready to go.\n\n" +
"Select whether you want to enable or disable reuseTriangles for the mesh\n" +
"nodes in your selection. The default setting is Enable. Confirm your choice\n" +
"with either the Set button (runs the script and closes the window) or with\n" +
"the Apply button (runs the script, leaves the windw open).\n\n" +
"The main window also has a menu to save and reset the settings.\n" +
"Save Settings saves the settings even if you don't run the script.\n" +
"Reset Settings resets the settings and - contrary to regular Maya\n" +
"windows - also resets the window position.") "helpUsageLongText"`;
setParent ..;
// "Purpose" frame
string $helpPurpose = `frameLayout
-l ("Purpose") -bs "etchedIn" -cll true -cl true
-pec ("senReuseTrianglesHelpMenuChangeLen(1, 1, senReuseTrianglesGetHelpMenuLen(\"" + $helpMenu + "\"), \"" + $helpMenu + "\")")
-pcc ("senReuseTrianglesHelpMenuChangeLen(1, 0, senReuseTrianglesGetHelpMenuLen(\"" + $helpMenu + "\"), \"" + $helpMenu + "\")")
-la center -li 5 -mw 10 -mh 10 "helpPurposeFrame"`;
string $helpPurposeText = `text -l ("By default Maya reevaluates triangles on the fly which may cause\n" +
"textures to flicker when you animate an object. The reuseTriangles\n" +
"attribute controls this. All mesh nodes have it.\n\n" +
"This script allows you to enable reuseTriangles so that Maya literally\n" +
"reuses the triangle positions from your object's bind pose instead of\n" +
"recalculating them on the fly. This in turn stops textures from flickering.") "helpPurposeText"`;
setParent ..;
// Create Close button and correctly align all elements
string $closeButton = `button -l "Close" -h 25 -c ("deleteUI(\"" + $helpMenu + "\")") "helpMenuCloseButton"`;
formLayout -e
-af $helpAbout top 5
-af $helpAbout left 5
-af $helpAbout right 5
-af $helpUsageShort left 5
-af $helpUsageShort right 5
-ac $helpUsageShort top 5 $helpAbout
-af $helpUsageLong left 5
-af $helpUsageLong right 5
-ac $helpUsageLong top 5 $helpUsageShort
-af $helpPurpose left 5
-af $helpPurpose right 5
-ac $helpPurpose top 5 $helpUsageLong
-af $closeButton bottom 5
-ap $closeButton left 0 33
-ap $closeButton right 0 66
$helpMenuFrame;
setParent ..;
}
// Set the selected meshes' reuseTriangles attributes and print a report
global proc senReuseTrianglesRtriSwitcher(int $rtriState, int $closeWindow, string $window, string $rtriRadioBtns) {
string $meshes[] = sort(`ls -sl -dag -lf -typ mesh`);
string $list;
string $listShort[];
string $resultOff = "reuseTriangles is now disabled for";
string $resultOn = "reuseTriangles is now enabled for";
string $result;
int $counter[] = {(size(`ls -sl`)), (size($meshes))};
if ($rtriState) $result = $resultOn;
else $result = $resultOff;
for ($element in $meshes) setAttr ($element + ".rtri") $rtriState;
if ($counter[1] >= 2) {
appendStringArray($listShort, $meshes, ($counter[1] - 1));
$list = (stringArrayToString($listShort, ", "));
$list = ($list + " and " + $meshes[$counter[1] - 1] + ".\n");
print ($result + " the " + $counter[1] + " mesh nodes " + $list);
}
else print ($result + " the mesh node " + $meshes[0] + ".\n");
senReuseTrianglesSaveSettings($rtriRadioBtns);
if ($closeWindow) senReuseTrianglesCloseWindow($window);
}
// Create layout with Status frame and radio button group
proc string layoutTopAndBottom(int $rtriState, int $counter[], string $window, string $layAll) {
string $rtriText = "reuseTriangles:";
string $texts[] = createTexts($counter);
string $annStatus = ("Script status: " + (match ("[^\n]*", $texts[0])) + " " + $texts[1]);
string $annSettings = $rtriText + " Enable " +
"to stop textures from flickering.";
// Create frame for Status and Settings
string $topFrame = `columnLayout -adj true -rs 5 -co both 5 "topFrame"`;
// Frame for status text and traffic light icon
string $statusFrame = `frameLayout
-l "Status" -bs "etchedIn"
-la center -li 5 -mw 5 -mh 5 "statusFrame"`;
string $statusForm = `formLayout -nd 100 "statusForm"`;
string $statusIcon = `formLayout
-w 15 -h 15
-bgc (float($texts[2])) (float($texts[3])) (float($texts[4])) "statusIcon"`;
setParent ..;
string $textColumn = `columnLayout
-adj true
-cal center "textColumn"`;
string $statusText = `text -ann $annStatus -l ($texts[0] + $texts[1]) "statusText"`;
setParent ..;
formLayout -e
-af $statusIcon left 5
-af $statusIcon top 5
-af $textColumn left 30
-af $textColumn right 0
$statusForm;
setParent ..;
setParent ..;
// Frame for radio button group
string $settingsFrame = `frameLayout
-l "Settings" -bs "etchedIn"
-la center -li 5 -mw 5 -mh 5 "settingsFrame"`;
string $radioColumn = `columnLayout
-adj true
-cal center "radioColumn"`;
string $rtriRadioBtns = `radioButtonGrp
-nrb 2 -vr -l $rtriText
-la2 "Enable" "Disable"
-ann $annSettings
-sl (2 - $rtriState) "rtriRadioBtns"`;
radioButtonGrp -e -cc ("senReuseTrianglesSetRadioBtnState(\"" + $rtriRadioBtns + "\")") $rtriRadioBtns;
setParent ..;
setParent ..;
setParent ..;
// Frame for the Set, Apply and Close buttons
string $bottomFrame = `formLayout -nd 20 "bottomFrame"`;
string $b1 = `button -l "Set" -h 25 -c ("senReuseTrianglesRtriSwitcher((senReuseTrianglesGetCurrentValue()), 1, \"" + $window + "\", \"" + $rtriRadioBtns + "\")") "setButton"`;
string $b2 = `button -l "Apply" -h 25 -c ("senReuseTrianglesRtriSwitcher((senReuseTrianglesGetCurrentValue()), 0, \"" + $window + "\", \"" + $rtriRadioBtns + "\")") "applyButton"`;
string $b3 = `button -l "Close" -h 25 -c ("senReuseTrianglesCloseWindow(\"" + $window + "\")") "closeButton"`;
if (!$counter[1]) {
button -e -en false $b1;
button -e -en false $b2;
}
// Correctly align the buttons
formLayout -e
-af $b1 bottom 5
-af $b1 left 5
-ap $b1 right 5 7
-an $b1 top
-af $b2 bottom 5
-ac $b2 left 5 $b1
-ac $b2 right 5 $b3
-an $b2 top
-af $b3 bottom 5
-af $b3 right 5
-ap $b3 left 5 13
-an $b3 top
$bottomFrame;
setParent;
// Correctly align the two frames
formLayout -e
-af $topFrame right 0
-af $topFrame left 0
-af $bottomFrame bottom 0
-af $bottomFrame right 0
-af $bottomFrame left 0
$layAll;
return $rtriRadioBtns;
}
// Either create formLayout or just update its content
global proc string senReuseTrianglesCreateLayout(int $rtriState, string $window, string $layout) {
windowPref -sa;
if (`formLayout -ex $layout`) {
deleteUI -lay $layout;
$rtriState = senReuseTrianglesGetCurrentValue();
}
int $counter[] = countObjs();
string $layAll = `formLayout -p $window $layout`;
string $rtriRadioBtns = (layoutTopAndBottom($rtriState, $counter, $window, $layAll));
setParent ..;
return $rtriRadioBtns;
}
// Create main window and fill in content
proc createWindow() {
string $script = "senReuseTriangles";
string $window = ($script + "Window");
string $layout = ($script + "Layout");
if (`window -ex $window`) deleteUI $window;
window -t $script -mb true -wh 400 250 $window;
int $rtriState = getSavedValue();
string $rtriRadioBtns = (senReuseTrianglesCreateLayout($rtriState, $window, $layout));
// Create Edit and Help menus
string $mainEditMenu = `menu -l "Edit" "editMenu"`;
string $mainEdit1 = `menuItem -l "Save Settings" -c ("senReuseTrianglesSaveSettings(\"" + $rtriRadioBtns + "\")") "editMenuSave"`;
string $mainEdit2 = `menuItem -l "Reset Settings" -c ("senReuseTrianglesResetSettings(\"" + $rtriRadioBtns + "\")") "editMenuReset"`;
string $mainHelpMenu = `menu -l "Help" -hm true "helpMenu"`;
string $mainHelp1 = `menuItem -l ("Help on " + $script) -c ("senReuseTrianglesHelpMenu(\"" + $script + "\")") "helpMenuHelp"`;
showWindow $window;
// Start a scriptJob to run as long as the window exists
int $jobNum = `scriptJob -e "SelectionChanged" ("senReuseTrianglesCreateLayout(\"" + $rtriState + "\", \"" + $window + "\", \"" + $layout + "\")") -p $window`;
}
// Procedure to start the script
global proc senReuseTriangles() {
createWindow();
}
senReuseTriangles MEL-Skript. Dieses Skript steuert das reuseTriangles-Attribut und somit das Texturflackern animierter Objekte. Zunächst überprüft es, ob die aktuelle Auswahl mindestens ein Meshnode enthält. Da ohnehin nur Meshnodes das reuseTriangles-Attribut (kurz rtri) haben, lässt sich das Skript nur ausführen, wenn mindestens eines in der Auswahl ist. Ist das der Fall, setzt das Skript rtri auf 0 oder 1 – je nachdem, was der Benutzer eingestellt hat. Zum Schluss meldet es, welche Nodes von der Änderung betroffen waren.
Dieses Skript herunterladen (6,79 KiByte) Maya 8 oder höher, funktioniert vermutlich auch mit früheren Versionen.
|
> |