Maya工具集合
2024年10月19日
记录一些Maya的实用工具
免费工具
- 来自 Dennis Porter 的 SmartMesh Tools -
https://github.com/Bartalon/SmartMesh-Tools/tree/master
复制下方代码-然后保存为dpSmartMeshTools.mel
后
将dpSmartMeshTools.mel
复制到 C:\Users\Owner\Documents\maya\2018\scripts
里
然后在脚本编辑器里输入
source dpSmartMeshTools.mel; dpSmartMeshTools;
然后回车
Code-view
dpSmartMeshTools.mel
//////////////////////////////////////
///// SmartMesh Tools ////
///// Version 1.0 ////
//////////////////////////////////////
// //
//////////////////////////////////////
//// Authored and Maintained by ////
//// ////
//// Dennis "Bartalon" Porter ////
//// ////
//// Dennis.Porter.3D@gmail.com ////
//// www.DennisPorter3D.com ////
//////////////////////////////////////
/*
Installation Instructions:
1) Fully exit Maya.
2) Paste dpSmartMeshTools.mel into C:\Users\Owner\Documents\maya\2013-x64\scripts
or equivalent scripts folder destination. Be sure to put it into the Scripts folder
located inside the 2013 folder (not the one inside the "maya" folder) or it won't install
properly.
3) Open Maya.
4) In Maya's MEL command line (or in the Script Editor), type in the following, then press enter:
source dpSmartMeshTools.mel; dpSmartMeshTools;
For updates check http://www.creativecrash.com/maya/script/smartmesh-tools
or www.DennisPorter3D.com/mel.htm
*/
global string $stRelease = "27 January 2015";
global string $stVersion = "1.1.0";
/////////////////////////////////
// User-Adjustable Variables //
/////////////////////////////////
// If you do not want custom naming conventions, set these values to 0 for each operation you
// do not want to automatically rename meshes.
// (Save and re-source script or re-open SmartMesh Tools window. Restarting Maya not required)
//
// ONLY USE VALUES 0 or 1
// 0 disables a feature
// 1 enables a feature
// Be careful not to delete the semicolons (there should be one at
// the end of each line in ths section
global int $st_CustomNames_Combine = 1;
global int $st_CustomNames_Separate = 1;
global int $st_CustomNames_Extract = 1;
global int $st_CustomNames_DupeFace = 1;
//////////////////////////////
// SmartMesh Tools Window //
//////////////////////////////
global proc dpSmartMeshTools() {
global string $stVersion;
string $buttonLabel[] = {
"Smart Combine",
"Smart Separate",
"Smart Extract",
"Smart Duplicate Face" };
string $buttonImage[] = {
"polyUnite.png",
"polySeparate.png",
"polyChipOff.png",
"polyDuplicateFacet.png" };
if (`window -ex stAboutWindow`) { deleteUI stAboutWindow; windowPref -remove stAboutWindow; }
if (`window -ex stBindHotkey`) { deleteUI stBindHotkey; windowPref -remove stBindHotkey; }
if (`window -ex smartMeshToolsWindow`) { deleteUI smartMeshToolsWindow; }
window -mxb 0 -mnb 0 -tlb 1 -title ("SmartMesh Tools v" + $stVersion) -w 200 smartMeshToolsWindow;
gridLayout -cellWidthHeight 225 32 -numberOfColumns 1;
for ($i=0; $i<4; ++$i) {
string $buttonCommand = "";
if ($i == 0) { $buttonCommand = "dpSmartCombine();"; }
if ($i == 1) { $buttonCommand = "dpSmartSeparate();"; }
if ($i == 2) { $buttonCommand = "dpSmartExtractDuplicate(1);"; }
if ($i == 3) { $buttonCommand = "dpSmartExtractDuplicate(0);"; }
gridLayout -cellWidth 161 -numberOfColumns 2;
iconTextButton -style "iconAndTextHorizontal" -l $buttonLabel[$i] -i $buttonImage[$i] -h 25 -c ( $buttonCommand );
gridLayout -cellWidth 32 -numberOfColumns 2;
iconTextButton -style "iconOnly" -image "SafeTitle.png" -ann "Bind a hotkey" -c ( "stHotkey(" + $i + ")" ) ;
iconTextButton -style "iconOnly" -image "factoryIcon.png" -ann "Create a shelf button" -c ( "dpSmartMeshToolButton(" + $i + ")" );
setParent..;
setParent..;
}
gridLayout -cellWidth 193 -numberOfColumns 2;
iconTextButton -style "textOnly" -l "Make a shelf button for this window" -c "dpSmartMeshToolButton(4);";
gridLayout -cellWidth 32 -numberOfColumns 1;
iconTextButton -style "iconOnly" -image "pickOtherComp.png" -ann "About SmartMesh Tools" -c "stAbout;";
setParent..;
setParent..;
setParent..;
showWindow smartMeshToolsWindow;
}
/////////////////////
// Smart Combine //
/////////////////////
global proc dpSmartCombine() {
global int $st_CustomNames_Combine;
//// Gather Info
// A. Check for at least 2 mesh objects
int $groupMeshes = (size(`listRelatives -type "mesh" (listRelatives("-f", "-type", "transform"))`));
int $singleMeshes = (size(`listRelatives -f -type "mesh"`));
if ($groupMeshes + $singleMeshes < 2) { error "Your selection must be, or be parents of, at least two mesh objects."; }
// B. Get Selection Groups
string $sel[] = `ls -l -sl`; // long names to avoid duplicate names under different parents
string $name[] = `ls -sl`; // for renaming groups
select -hi $sel;
select -d `ls -s -sl`; // omits shape objects
string $allObjects[] = `ls -l -sl`; // for instancing purposes
select $sel;
// C. Store Raw Groups Long Names
string $untokenizedGroups[];
for ($obj in $sel) {
$untokenizedGroups = stringArrayCatenate($untokenizedGroups, `listRelatives -f -p $obj`);
}
string $rawGroupsCount[] = $untokenizedGroups; // Provides a count of all parents of selection (for determining destination)
$untokenizedGroups = stringArrayRemoveDuplicates($untokenizedGroups);
// D. Tokenize Raw Groups
string $buffer[];
string $destinationGroups[];
for ($obj in $untokenizedGroups) { // For unique groups
tokenize $obj "|" $buffer;
$destinationGroups[`size $destinationGroups`] = $buffer[`size $buffer`-1];
}
string $groupsCounter[];
for ($obj in $rawGroupsCount) {
tokenize $obj "|" $buffer;
$groupsCounter[`size $groupsCounter`] = $buffer[`size $buffer`-1];
}
// E. Determine Mesh Destination
int $count;
int $index;
for ($i=0; $i<`size $destinationGroups`; ++$i) { // For counting group occupancy size
if (stringArrayCount($destinationGroups[$i], $groupsCounter) > $count) {
$count = stringArrayCount($destinationGroups[$i], $groupsCounter);
$index = $i;
}
}
// F. Determine name of final combined mesh
int $sequence;
string $combinedName;
while (`objExists ("SmartCombine_" + $sequence)`) { ++$sequence; }
if ($singleMeshes == 0) { // if only groups were selected for union
string $uniqueNames[];
for ($a in $name) { // rule out anything containing "SmartGroup"
if (`gmatch $a "SmartGroup*"` == 0) {
$uniqueNames[`size $uniqueNames`] = $a;
}
}
if (`size $uniqueNames` == 1) { $combinedName = $uniqueNames[0]; }
else if (`size $uniqueNames` > 1) {
string $prompt = `confirmDialog
-title ""
-message "Pick the most suitable name for your new mesh"
-button $uniqueNames[0]
-button $uniqueNames[1]
-button ("SmartCombine_" + $sequence)`;
$combinedName = $prompt;
}
else { $combinedName = ("SmartCombine_" + $sequence); } // catches any anomalies to make sure operation still executes
}
else { $combinedName = ("SmartCombine_" + $sequence); }
// G. Prepare Names (avoids errors caused by duplicate instance names)
int $prepTicker;
for ($i=`size $allObjects`-1; $i>-1; --$i) {
if (objExists ("CombinePrep_" + $prepTicker)) { ++$prepTicker; }
$allObjects[$i] = `rename $allObjects[$i] ("CombinePrep_" + $prepTicker)`;
}
// H. Store Instance Meshes
string $allInstances[];
for ($a in $allObjects) {
select $a;
if (size(`listRelatives -ap (listRelatives("-f", "-s"))`) > 1) { $allInstances[`size $allInstances`] = $a; }
}
//// Do The Things
// 1. Rename & Convert Instances
if ($singleMeshes == 0) { ConvertInstanceToObject; } // makes sure group-only selections are not instances
select $allInstances;
ConvertInstanceToObject;
// 2. Actually Combine
select $allObjects;
CombinePolygons;
DeleteHistory;
CenterPivot;
if ($st_CustomNames_Combine == 0) { // This is for if the user does not want the custom naming conventions
string $newName[] = `ls -sl`;
$combinedName = $newName[0];
}
rename $combinedName;
// 3. Cleanup
for ($a in $allObjects) {
if (`objExists $a` && $a != $combinedName && $a != ("|" + $combinedName)) { delete $a; }
}
// 4. Return to Group
if (`objExists $untokenizedGroups[$index]`) {
parent $combinedName $untokenizedGroups[$index];
}
}
//////////////////////
// Smart Separate //
//////////////////////
global proc dpSmartSeparate() {
global int $st_CustomNames_Separate;
// Currently does not correctly separate objects with children, but it doesn't seem to inadvertently delete anything either.
string $oldName[];
string $newName[];
float $pivot[];
//// Gather Info
// A. Make sure ls belongs to exactly 1 mesh
if (size(`listRelatives -p`) > 1 || size(`ls -sl`)>1) { error ("Separate only one mesh at a time."); }
if (size(`ls -sl`) == 0) { error ("Nothing selected."); }
if (size(`listRelatives -type "mesh" -p`) == 0 && size(`listRelatives -type "mesh" -c`) == 0) { error ("Invalid selection. Select a mesh object to separate."); }
// B. Get mesh name
$oldName = `ls -l -sl`;
// C. Figure out if object has _Sep_ already and remove it
if (`gmatch $oldName[0] "*_Sep_*"`) {
string $buffer[];
tokenize $oldName[0] "_" $buffer;
for ($slot in $buffer) {
if ($slot != "Sep") { $newName[0] = ($newName[0] + $slot); }
else { break; }
}
}
else { $newName[0] = $oldName[0]; }
$newName[0] = ($newName[0] + "_Sep_1");
if (`gmatch $newName[0] "*Smart*"`) { $newName[0] = "SmartSeparate_1"; }
// D. Store pivot location
$pivot = `xform -q -ws -a -piv`;
//// Do the things
// 1. Convert instance
if (size(`listRelatives -ap (listRelatives("-f", "-s"))`) > 1) { ConvertInstanceToObject; }
// 2. Clear history, Separate delete group
DeleteHistory;
SeparatePolygon;
if (size(`ls -sl`) == 1) { error "Mesh has no elements to separate."; }
DeleteHistory;
pickWalkUp;
Ungroup;
// 3. Rename all bits
if ($st_CustomNames_Separate == 1) { // This is for if the user does not want the custom naming conventions
for ($chip in `ls -sl`) { rename $chip $newName[0]; }
}
// 4. Reposition pivot
xform -ws -a -rp $pivot[0] $pivot[1] $pivot[2];
xform -ws -a -sp $pivot[0] $pivot[1] $pivot[2];
}
//////////////////////
// Smart Extract //
// Smart Duplcate //
//////////////////////
// Extract and duplicate function similarly, with the only real difference being Extract
// does not leave the selected faces behind on the old object
global proc dpSmartExtractDuplicate(int $option) {
global int $st_CustomNames_DupeFace;
global int $st_CustomNames_Extract;
string $mode[] = { "Duplicate", "Extract" };
string $match[] = { "*_Dup_*", "*_Ext_*" };
string $suffix[] = { "_Dup_1", "_Ext_1" };
string $newName[];
string $buffer[];
string $newFaces[];
// Gather Info
// A. Make sure ls belongs to exactly 1 mesh
if (size(`listRelatives -p`) > 1) { error ($mode[$option] + " faces from one mesh at a time."); }
if (size(`listRelatives -p`) == 0) { error ("Select a component to " + $mode[$option]); }
if (size(`listRelatives -type "mesh" -p`) == 0) { error ("Invalid selection. Select a mesh component to " + $mode[$option] + "."); }
// B. Convert to Faces and store selection
ConvertSelectionToFaces;
string $oldFaces[] = `ls -l -fl -sl`;
// C. Store mesh belonging to components
string $oldName[] = `listRelatives -f -p (listRelatives("-p","-f", $oldFaces[0]))`;
// D. Check if mesh already contains _Dup_ or _Ext_
if (`gmatch $oldName[0] $match[$option]`) {
// E. Tokenize & adjust for final chronological name
tokenize $oldName[0] "_" $buffer;
for ($slot in $buffer) {
if ($slot != "Dup" && $slot != "Ext") { $newName[0] = ($newName[0] + $slot); }
else { break; }
}
}
else { $newName[0] = $oldName[0]; }
$newName[0] = ($newName[0] + $suffix[$option]);
if (`gmatch $newName[0] "*Smart*"` && $option == 0) { $newName[0] = "SmartDuplicate_1"; }
if (`gmatch $newName[0] "*Smart*"` && $option == 1) { $newName[0] = "SmartExtract_1"; }
//// Do The Things
// 1. Duplicate
if ($st_CustomNames_DupeFace == 1 && $option == 0) { // Duplicate Face
$newName = `duplicate -n $newName[0] $oldName[0]`;
}
else if ($st_CustomNames_Extract == 1 && $option == 1) { // Extract
$newName = `duplicate -n $newName[0] $oldName[0]`;
}
else if ($option == 1 || $option == 0) {
$newName = `duplicate $oldName[0]`;
}
// 2. Switch over components from old name to new name
for ($i=0; $i<`size $oldFaces`; ++$i) {
tokenize $oldFaces[$i] "." $buffer;
$newFaces[$i] = ($newName[0] + "." + $buffer[1]);
}
// 3. Delete Children
select `listRelatives -f -c $newName[0]`;
select -d `ls -type "mesh" -sl`;
if (size(`ls -sl`) > 0) { delete; }
// 4. Delete appropriate faces on new
select $newName[0];
ConvertSelectionToFaces;
select -d $newFaces;
delete;
// 5. If Extract, delete faces on old (wont delete anything if duplicating face)
if ($option == 1) { delete $oldFaces; }
select $newName[0];
selectMode -o;
}
/////////////////////
// Shelf Buttons //
/////////////////////
global proc dpSmartMeshToolButton(int $option) {
global string $gShelfTopLevel;
global string $stVersion;
string $currentShelf = `tabLayout -q -st $gShelfTopLevel`;
setParent ($gShelfTopLevel + "|" + $currentShelf);
switch ($option) {
case 0:
shelfButton
-label "Smart Combine"
-annotation "Smart Combine"
-image1 "polyUnite.png"
-command "source dpSmartMeshTools.mel; dpSmartCombine;";
break;
case 1:
shelfButton
-label "Smart Separate"
-annotation "Smart Separate"
-image1 "polySeparate.png"
-command "source dpSmartMeshTools.mel; dpSmartSeparate;";
break;
case 2:
shelfButton
-label "Smart Extract"
-annotation "Smart Extract"
-image1 "polyChipOff.png"
-command "source dpSmartMeshTools.mel; dpSmartExtractDuplicate(1);";
break;
case 3:
shelfButton
-label "Smart Duplicate Face"
-annotation "Smart Duplicate Face"
-image1 "polyDuplicateFacet.png"
-command "source dpSmartMeshTools.mel; dpSmartExtractDuplicate(0);";
break;
case 4:
shelfButton
-label ( "SmartMesh Tools v" + $stVersion )
-annotation "Launch SmartMesh Tools Window"
-image1 "polyAssignSubdivHole.png"
-command "source dpSmartMeshTools.mel; dpSmartMeshTools;";
break;
warning "Shelf button created.";
}
}
///////////////////////
// Binding Hotkeys //
///////////////////////
global proc stHotkey(int $option) {
global string $stVersion;
string $title[] = {
"Bind Hotkey for Smart Combine",
"Bind Hotkey for Smart Separate",
"Bind Hotkey for Smart Extract",
"Bind Hotkey for Smart Duplicate Face" };
string $descrip[] = {
"This hotkey will perform a smarter version of Maya's default operation of \"Mesh > Combine\".",
"This hotkey will perform a smarter version of Maya's default operation of \"Mesh > Separate\".",
"This hotkey will perform a smarter version of Maya's default operation of \"Mesh > Extract\".",
"This hotkey will perform a smarter version of Maya's default operation of \"Edit Mesh > Duplicate Face\"." };
string $recommend[] = {
"(Recommended Ctrl + Alt + Shift + C)",
"(Recommended Ctrl + Alt + Shift + S)",
"(Recommended Ctrl + Alt + Shift + E)",
"(Recommended Ctrl + Alt + Shift + D)" };
string $key[] = {
"C",
"S",
"E",
"D" };
if (`window -exists stBindHotkey`) {
deleteUI stBindHotkey;
windowPref -remove stBindHotkey;
}
window -mxb 0 -mnb 0 -tlb 1 -title $title[$option] -w 200 stBindHotkey;
gridLayout -numberOfColumns 1 -cellWidthHeight 300 185;
gridLayout -numberOfColumns 1 -cellWidthHeight 300 135;
scrollField -wordWrap true -editable false
-text ("Choose a desired hotkey. The hotkey is case sensitive!\n\n" + $descrip[$option] + "\n\n" + $recommend[$option]);
gridLayout -numberOfColumns 3 -cellWidthHeight 100 50;
gridLayout -numberOfColumns 1 -cellWidthHeight 75 50;
textFieldGrp -text $key[$option] hotkeyField;
setParent..;
gridLayout -numberOfColumns 2 -cellWidthHeight 50 50;
checkBox -label "Alt" -v 1 altCheck;
checkBox -label "Ctrl" -v 1 ctrlCheck;
setParent..;
gridLayout -numberOfColumns 1 -cellWidthHeight 100 50;
if ( $option == 0 ) { button -label "ASSIGN" -command "stMenuHotkey(0)"; }
else if ( $option == 1) { button -label "ASSIGN" -command "stMenuHotkey(1)"; }
else if ( $option == 2) { button -label "ASSIGN" -command "stMenuHotkey(2)"; }
else if ( $option == 3) { button -label "ASSIGN" -command "stMenuHotkey(3)"; }
setParent..;
setParent..;
setParent..;
setParent..;
showWindow stBindHotkey;
setFocus hotkeyField;
}
global proc stMenuHotkey(int $option) {
int $keyLength;
string $namedCmd;
string $hotkeyAnn[] = { "Smart Combine", "Smart Separate", "Smart Extract", "Smart Duplicate Face" };
$key = `textFieldGrp -q -text hotkeyField`;
$keyLength = `size $key`;
$alt = `checkBox -q -v "altCheck"`;
$ctrl = `checkBox -q -v "ctrlCheck"`;
if ( $keyLength > 1 ) { error "Hotkey must be a single character."; }
if ( $key == " " ) { error "Hotkey may not be bound to the space bar."; }
if ( $key == "" ) { error "Hotkey must be a single character."; }
string $rebindConfirm = `confirmDialog
-title "Confirm hotkey bind"
-message "Are you sure you want to bind this hotkey? This is NOT undoable and will remain bound until you change the binding in the Hotkey Editor."
-button "Bind It"
-button "Cancel"
-defaultButton "Cancel"
-cancelButton "Cancel"
-dismissString "Cancel"`;
if ( $rebindConfirm == "Bind It" ) {
if ( $option == 0 ) {
nameCommand -annotation $hotkeyAnn[$option] -command "source dpSmartMeshTools; dpSmartCombine;" dpSmartCombineNamedCommand;
$namedCmd = "dpSmartCombineNamedCommand";
}
else if ( $option == 1 ) {
nameCommand -annotation $hotkeyAnn[$option] -command "source dpSmartMeshTools; dpSmartSeparate;" dpSmartSeparateNamedCommand;
$namedCmd = "dpSmartSeparateNamedCommand";
}
else if ( $option == 2 ) {
nameCommand -annotation $hotkeyAnn[$option] -command "source dpSmartMeshTools; dpSmartExtractDuplicate(1);" dpSmartExtractNamedCommand;
$namedCmd = "dpSmartExtractNamedCommand";
}
else if ( $option == 3 ) {
nameCommand -annotation $hotkeyAnn[$option] -command "source dpSmartMeshTools; dpSmartExtractDuplicate(0);" dpSmartDupeFaceNamedCommand;
$namedCmd = "dpSmartDupeFaceNamedCommand";
}
if ( $alt == "0" && $ctrl == "0" ) {
hotkey -k $key -name $namedCmd;
warning ( "Hotkey assigned to the " + $key + " key." );
}
else if ( $alt == "1" && $ctrl == "0" ) {
hotkey -k $key -alt -name $namedCmd;
warning ( "Hotkey assigned to Alt + " + $key + "\"." );
}
else if ( $alt == "0" && $ctrl == "1" ) {
hotkey -k $key -ctl -name $namedCmd;
warning ( "Hotkey assigned to Ctrl + " + $key + "\"." );
}
else if ( $alt == "1" && $ctrl == "1" ) {
hotkey -k $key -alt -ctl -name $namedCmd;
warning ( "Hotkey assigned to Alt + Ctrl + " + $key + "\"." );
}
}
deleteUI stBindHotkey;
windowPref -remove stBindHotkey;
}
////////////////////
// About Button //
////////////////////
global proc stAbout() {
global string $stVersion;
global string $stRelease;
if (`window -exists stAboutWindow`) {
deleteUI stAboutWindow;
windowPref -remove stAboutWindow;
}
window -mxb 0 -mnb 0 -tlb 1 -title "About SmartMesh Tools" -w 400 stAboutWindow;
gridLayout -numberOfColumns 1 -cellWidthHeight 400 175;
gridLayout -numberOfColumns 1 -cellWidthHeight 400 150;
scrollField -wordWrap true -editable false
-text ( "SmartMesh Tools v" + $stVersion + " released " + $stRelease + " for Maya 2012 thru 2015.\n\nContact Dennis.Porter.3D@gmail.com with any bugs, comments, or questions.\n\nRefer to commented lines at the top of the .mel file for script information and modification instructions." );
gridLayout -numberOfColumns 3 -cellWidthHeight 200 25;
iconTextButton -style "textOnly" -l "SmartMesh Tools on CreativeCrash" -c "system(\"shell start http://www.creativecrash.com/maya/script/smartmesh-tools\");";
iconTextButton -style "textOnly" -l "Author Website" -bgc .2 .2 .2 -c "system(\"shell start http://dennisporter3d.com/mel.htm\");";
setParent..;
setParent..;
setParent..;
showWindow stAboutWindow;
}
说明
这个脚本替换了Maya默认的合并、分离、提取和复制面操作。
通用功能:
- 清晰的构建历史 - 合并、分离、提取或复制面时,不再有遗留的组。
- 特定命名规范 - 不再有神秘的“polySurface”对象。
- 快速热键实现
智能合并:
合并的对象将会:
- 重命名为
SmartCombine_#
。 - 自动将其中心点设置为中心,而不是默认的原点。
- 尽量保留在其原始组内(如果有的话),或者保留在包含最多操作对象的组内。
- 不会导致实例化对象消失。
- 永远不会共享相同的短名称,即使嵌套在组内。
- 如果整个组被合并,将继承该组的名称(例如,一个包含25个对象的组名为Gun,则合并后将自动命名为Gun)。
智能分离:
分离的对象将会:
- 保留原始对象的名称,并附加后缀
_Sep
(例如,TestMesh将分离为TestMesh_Sep_1和TestMesh_Sep_2),因此在Outliner/Hypergraph中仍然可以识别分离对象的起源。 - 保留原始对象的中心点,而不是默认的原点。
- 保留在其组内。
- 不会导致实例化对象消失。
智能提取:
提取的对象将会:
- 保留原始对象的名称,并附加后缀
_Ext
。 - 保留原始对象的中心点,而不是默认的原点。
- 不会在其原始网格上生成
polyChipOff
节点,而是生成deleteComponent
节点。 - 保持清晰的构建历史,并且不会与其原始网格链接(在提取元素上删除历史记录不会删除原始网格上的历史记录)。
- 即使选择多个不连续的元素,也会保持为一个对象(常规提取会将每个元素作为单独的对象)。
智能复制面:
复制的面将会:
- 保留原始对象的名称,并附加后缀
_Dup
。 - 保留原始对象的中心点,而不是默认的原点。
- 不会影响原始网格的构建历史!这意味着你可以在已绑定网格或其他复杂历史对象上复制面,并保留其历史记录。
- 不会影响实例化对象。
- 保留在其组内。
附加功能:
- 自动热键绑定。
- 自动创建工具栏按钮。
历史版本
添加了用户控制变量:
用户现在可以通过设置变量来决定是否使用自定义命名规范。(请参见.mel文件中的前几行注释)修复了绑定自定义热键的问题:
修正了一个问题,即绑定自定义热键时无法正常工作。
修复智能分离的问题:
- 修正了在对没有元素可分离的组对象使用智能分离时,会意外取消该组的问题。
增加额外信息(未完待续)
- 来自 Klaudio Ladavac 免费工具 -
颜色id工具;镜像工具;测量工具;楔角工具;选择相似工具
- Ari UV工具集 -
UV-工具集
地址: cgjishu.net
调用某个插件
source "Ari/AriUVGriddingOptions.mel"; //面板
source "Ari/AriUVGridding.mel"; //功能
AriUVGriddingOptions();
- Im3dJoe - Maya Polygon Lab -
Im3dJoe工作室免费分享的一些超棒工具
部分截图
- 来自 Adnan Chaumette 免费工具 -
每一项都很好用-还有使用说明
下载地址
- ig_EzRename change -
作者:igorsilva
一款开源的maya重命名工具;
在原有基础上进行了一小部分的改动,更符合个人工作习惯。
Code-view
ig_EzRename1.2
#--------------------------------------------------------------------------------#
# Teste only in maya 2018+
#
#
# ig_EzRename.py
# version 1.2, last modified 26/10/2020
# Copyright (C) 2020 Igor Silva
# Email: igorsilva.design@gmail.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# See http://www.gnu.org/licenses/gpl.html for a copy of the GNU General
# Public License.
#version 1.1
#Fixed the tool was not working with objects with the same name
# Fixed Hierarchy mode search and replace
# Fixed All mode search and replace
#--------------------------------------------------------------------------------#
# I N S T A L L A T I O N:
#
# Copy the "EzRename.py" to your Maya scripts directory:
# MyDocuments\Maya\scripts\
# use this text as a python script within Maya:
#
#--------------------------------------------------------------------------------#
# I N S T A L L A T I O N:
#
# Copy the "ig_EzRename.py" to your Maya scripts directory:
# MyDocuments\Maya\scripts\
# use this text as a python script within Maya:
'''
import ig_EzRename
reload(ig_EzRename)
ig_EzRename.UI()
'''
# this text can be entered from the script editor and can be made into a button
#--------------------------------------------------------------------------------#
# EzRename.py
# ast modified 23/07/2022
# Editor : zhubin (email:2624203622@qq.com)
# Based on igEzRename,Modified.
#
#--------------------------------------------------------------------------------#
import maya.cmds as cmds
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
def utf_8String(StringT):
utf_8String = StringT
utf_8String.encode('utf-8')
utf_8String = unicode(utf_8String, "utf-8")
return utf_8String
def UI():
global SelectName
global RenameText
global StartValue
global PaddingValue
global NumberCheck
global RemoveFirst
global RemoveEnd
global PrefixText
global SuffixText
global SearchText
global ReplaceText
global SRCheck
#UI Width
sizeX = 240
version = "v1.0"
if cmds.window("EzRenameWin", exists=True):
cmds.deleteUI("EzRenameWin", window=True)
#Creating UI
igEzRenamWin = cmds.window("EzRenameWin", title="Easy Rename Tool"+version, width=sizeX+6, height=300, mnb = True, mxb = False, sizeable = False)
#Creating interface elements
mainLayout = cmds.columnLayout("mainColumnLayout", width = sizeX, adjustableColumn=False, co = ["both",2])
#Select All Button
cmds.separator(h=5, style = "none", parent = mainLayout)
cmds.button(label = "Select All", w=sizeX, h=25, c=SelectAll, ann = "Select ALL objects in scene")
cmds.separator(h=5, style = "none", parent = mainLayout)
#Rename and Number
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)])
#Rename Field
cmds.text(label=" Rename:", font = "boldLabelFont", w = sizeX/4, align="left", ann="Write the name you want to rename the objects selected")
RenameText = cmds.textField(w = sizeX*0.75, ann="Write the name you want to rename the objects selected")
#Start Field
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)])
cmds.text(label=" 开始数:", font = "boldLabelFont", w = sizeX/4, align="left")
StartValue = cmds.textField(w = sizeX/4, tx="1", ann="Write the Start value for the sequence")
#Padding Field
cmds.text(label=" 位数:", font = "boldLabelFont", w = sizeX/4, align="left")
PaddingValue = cmds.textField(w = sizeX/4, tx="2", ann="Write the Padding value for the numbers")
#Number Letters
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)])
cmds.text(label="", font = "boldLabelFont", w = sizeX/4-2, align="left")
NumberCheck = cmds.radioButtonGrp(labelArray2=[ '按数字', '按字母'], numberOfRadioButtons=2, w=sizeX, h=20, sl=1, cw = ([1,120]))
#ButtonRename and Number
cmds.separator(h=5, style = "none", parent = mainLayout)
cmds.button(label = "重命名并排序", w=sizeX, h=25, c=RenameNumber, align = "Center", parent = mainLayout)
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#RemoveCharacter
#Remove First/Last
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 25), (2, 60)], cs = [(5,5)])
cmds.text(label=" 删除:", font = "boldLabelFont", w = sizeX/3-12, align="left")
cmds.button(label = "第一个字符->", w=sizeX/3, h=25, c="Remove(True)", align = "Center")
cmds.button(label = "<-最后的字符", w=sizeX/3, h=25, c="Remove(False)", align = "Center")
cmds.separator(h=5, style = "none", parent = mainLayout)
#Remove pasted__
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 25), (2, 60)], cs = [(90,90)])
cmds.text(label="del pasted all", font = "boldLabelFont", w = sizeX/3-12, align="left")
cmds.button(label = "pasted__", w=50, h=25, c=RemovePasted,)
#Remove UI
cmds.separator(h=5, style = "none", parent = mainLayout)
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 25), (2, 60)], cs = [(8.5,8.5)])
RemoveFirst = cmds.textField(w = sizeX/5, tx="0", ann="Write the amount of characters you want to delete on text beginning")
cmds.button(label = "-", w=25, h=25, c="RemoveChar('begin')", align = "Center", ann="Delete on text beginning")
cmds.button(label = "删除", w=sizeX/4, h=25, c="RemoveChar('all')", align = "Center", ann="删除0-n自定义的字符")
cmds.button(label = "-", w=25, h=25, c="RemoveChar('end')", align = "Center", ann="Delete on text ending")
RemoveEnd = cmds.textField(w = sizeX/5, tx="3", ann="Write the amount of characters you want to delete on text ending")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Suffix
#Control Suffix
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 前缀:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the prefix")
PrefixText = cmds.textField(w = sizeX/2.5+33, tx="prefix_", ann="Write the prefix")
cmds.button(label = "Add", w=sizeX/4-10, h=25, c="PrefixSuffix(False)", align = "Center")
cmds.separator(h=5, style = "none", parent = mainLayout)
#Group Suffix
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 后缀:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the suffix")
SuffixText = cmds.textField(w = sizeX/2.5+33, tx="_suffix", ann="Write the suffix")
cmds.button(label = "Add", w=sizeX/4-10, h=25, c="PrefixSuffix(True)", align = "Center")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Prefix
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.button(label = "SM_", w=sizeX/5-4, h=25, c="Prefix('SM_')", align = "Center", ann = "Add SM_ Prefix")
cmds.button(label = "UCX_", w=sizeX/5-4, h=25, c="Prefix('UCX_')", align = "Center", ann = "Add SM_ Prefix")
cmds.button(label = "_low", w=sizeX/5-4, h=25, c="Suffix('_low')", align = "Center", ann = "Add _low suffix")
cmds.button(label = "_high", w=sizeX/5-4, h=25, c="Suffix('_high')", align = "Center", ann = "Add _high suffix")
cmds.button(label = "_old", w=sizeX/5-4, h=25, c="Suffix('_old')", align = "Center", ann = "Add _old suffix")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Custom
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label="组:", font = "boldLabelFont", w=20, h=25, align="left", ann="Write the text to search")
cmds.button(label = "Baking", w=60, h=25, c="toGroup('Baking')", align = "Center", ann = "replace Baking")
cmds.button(label = "Collision", w=60, h=25, c="toGroup('Collision')", align = "Center", ann = "replace Collision")
cmds.button(label = "Reference", w=60, h=25, c="toGroup('Reference')", align = "Center", ann = "replace Reference")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Search and Replace
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 搜索:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the text to search")
SearchText = cmds.textField(w = sizeX/2+100, ann="Write the text to search")
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 替换:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the text to replace")
ReplaceText = cmds.textField(w = sizeX/2+100, ann="Write the text to replace")
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
SRCheck = cmds.radioButtonGrp(labelArray3=[ '选择', '层级', 'All'], numberOfRadioButtons=3, w=sizeX, h=20, sl=1, cw = ([1,95],[2,95],[3,95]))
cmds.button(label = "Apply", w=sizeX, h=25, c=SearchReplace, align = "Center", parent = mainLayout)
cmds.separator(h=5, style = "none", parent = mainLayout)
#miaomiao
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text("P._( :> )_")
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text("Friends, hope you can be happy every day!")
#Show UI:
cmds.showWindow(igEzRenamWin)
def SelectAll(*args):
cmds.select(ado=True, hi = True)
selection = cmds.ls(selection=True, sn=True)
selectionAdd = []
#Old select all code version
"""for objs in selection:
children = cmds.listRelatives(objs, c=True, f =True)
print "Children01:", children
shapes = cmds.listRelatives(objs, s=True, f = True)
print "Shapes:", shapes
if not children == None:
if not shapes == None:
for s in shapes:
children.remove(s)
for chi in children:
children2 = cmds.listRelatives(chi, c=True, f = True)
print "CHildren02:", children2
if not children2 == None:
for chi2 in children2:
children.append(chi2)
selectionAdd.append(chi)
for objs in selectionAdd:
cmds.select(objs, add=True)"""
def SelectName(*args):
cmds.select(cl=True)
name = cmds.textField(SelectName, text = 1, q=True)
try:
selection = cmds.ls(name, l = True)
except:
cmds.warning("Object Don't Exist")
for objs in selection:
cmds.select(objs, add=True)
def RenameNumber(*args):
number = cmds.textField(StartValue, text = 1, q=True)
number = int(number)
padding = cmds.textField(PaddingValue, text = 1, q=True)
padding = int(padding)
NumberLetters = cmds.radioButtonGrp(NumberCheck, q=True, select=True)
newName = cmds.textField(RenameText, text = 1, q=True)
selection = cmds.ls(selection=True, sn=True)
lettersList = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
#Number suffix
y = 0
for obj in selection:
try:
#Teste if has duplicate mesh with the same name on the scene and return the name without parents
trueName = testDuplicateName(obj)
#Save the original name
oldName = trueName
#If true use numbers, else use letters
if NumberLetters == 1:
zeros = ""
for x in xrange(int(padding)):
if len(str(number)) <= x:
zeros = zeros+"0"
#Create the newName and rename
name = newName+"_"+"{:0>"+str(padding)+"}"
newNameList = name.format(number)
cmds.rename(obj, name.format(number))
else:
newNameList = newName+"_"+lettersList[y]
cmds.rename(obj, newName+"_"+lettersList[y])
if y < len(lettersList)-1:
y+=1
else:
y=0
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, newNameList)
selection[x] = newParentName
except:
pass
number = int(number+1)
def RemoveChar(Type):
first = cmds.textField(RemoveFirst, text = 1, q=True)
end = cmds.textField(RemoveEnd, text = 1, q=True)
selection = cmds.ls(selection = True, sn=True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
if Type == "all":
name = trueName[:-int(end)]
name = name[int(first):]
if Type == "begin":
name = trueName[int(first):]
if Type == "end":
name = trueName[:-int(end)]
try:
cmds.rename(objs, str(name))
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, name)
selection[x] = newParentName
def Remove(Type):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
if Type:
name = trueName[1:]
else:
name = trueName[:-1]
try:
cmds.rename(objs, name)
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, name)
selection[x] = newParentName
def RemovePasted(*args):
selection = cmds.ls("pasted__*", sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
name = trueName[8:]
try:
cmds.rename(objs, name)
except:
cmds.warning("Don't Exist pasted Objects")
def PrefixSuffix(Suffix):
prefix = cmds.textField(PrefixText, text = 1, q=True)
suffix = cmds.textField(SuffixText, text = 1, q=True)
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
if Suffix:
name = str(trueName)+suffix
else:
name = prefix+str(trueName)
try:
cmds.rename(objs, name)
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, name)
selection[x] = newParentName
#add Suffix
def Suffix(Text):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
newName = trueName+Text
try:
cmds.rename(objs, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
#add prefix
def Prefix(Text):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
newName = Text+trueName
try:
cmds.rename(objs, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
#Custom
def Custom(Text):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
newName = Text
try:
cmds.rename(objs, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
#toGroup
def toGroup(Text):
selection = cmds.ls(selection = True, sn = True)
cmds.group( n=Text )
def SearchReplace(*args):
search = cmds.textField(SearchText, text = 1, q=True)
replace = cmds.textField(ReplaceText, text = 1, q=True)
SRMethod = cmds.radioButtonGrp(SRCheck, q=True, select=True)
#Selected search and Replace method
if SRMethod == 1:
selection = cmds.ls(selection = True, sn = True)
#Hierarchy search and Replace method
if SRMethod == 2:
cmds.select(hi = True)
selection = cmds.ls(selection = True, sn = False)
#All search and Replace method
if SRMethod == 3:
#Select All DagObjects in scene
selection = []
cmds.select(ado = True, hi = True)
selection = cmds.ls(selection = True, sn=False)
#for to rename the objects
for obj in selection:
#Teste if has duplicate mesh with the same name on the scene and return the name without parents
trueName = testDuplicateName(obj)
#Save the original name
oldName = trueName
#Search and replace to create the new name
newName = trueName.replace(search, replace)
#Rename the object
try:
cmds.rename(obj, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in xrange(len(selection)):
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
print "Slecao: ", selection
def testDuplicateName(Obj):
try:
trueName = Obj.split("|")
return trueName[len(trueName)-1]
except:
return Obj
UI()
自改版本
#--------------------------------------------------------------------------------#
# EzRename.py
# ast modified 23/07/2022
# Editor : zhubin (email:2624203622@qq.com)
# Based on igEzRename,Modified.
#
#--------------------------------------------------------------------------------#
# importlib 模块
# 在 Python 3 中,reload 函数被移到了 importlib 模块中
# 这样导入可以确保脚本在 Python 2 和 Python 3 环境下都能正常工作
# 在开发过程中,reload 函数允许我们在不重启 Maya 的情况下重新加载更新后的模块
import maya.cmds as cmds
from importlib import reload
import sys
# 删除或注释掉这两行
# reload(sys)
# sys.setdefaultencoding('utf-8')
def utf_8String(StringT):
return StringT
def UI():
global SelectName
global RenameText
global StartValue
global PaddingValue
global NumberCheck
global RemoveFirst
global RemoveEnd
global PrefixText
global SuffixText
global SearchText
global ReplaceText
global SRCheck
#UI Width
sizeX = 240
version = "v1.0"
if cmds.window("EzRenameWin", exists=True):
cmds.deleteUI("EzRenameWin", window=True)
#Creating UI
igEzRenamWin = cmds.window("EzRenameWin", title="Easy Rename Tool"+version, width=sizeX+6, height=300, mnb = True, mxb = False, sizeable = False)
#Creating interface elements
mainLayout = cmds.columnLayout("mainColumnLayout", width = sizeX, adjustableColumn=False, co = ["both",2])
#Select All Button
cmds.separator(h=5, style = "none", parent = mainLayout)
cmds.button(label = "Select All", w=sizeX, h=25, c=SelectAll, ann = "Select ALL objects in scene")
cmds.separator(h=5, style = "none", parent = mainLayout)
#Rename and Number
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)])
#Rename Field
cmds.text(label=" Rename:", font = "boldLabelFont", w = sizeX/4, align="left", ann="Write the name you want to rename the objects selected")
RenameText = cmds.textField(w = sizeX*0.75, ann="Write the name you want to rename the objects selected")
#Start Field
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)])
cmds.text(label=" 开始数:", font = "boldLabelFont", w = sizeX/4, align="left")
StartValue = cmds.textField(w = sizeX/4, tx="1", ann="Write the Start value for the sequence")
#Padding Field
cmds.text(label=" 位数:", font = "boldLabelFont", w = sizeX/4, align="left")
PaddingValue = cmds.textField(w = sizeX/4, tx="2", ann="Write the Padding value for the numbers")
#Number Letters
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)])
cmds.text(label="", font = "boldLabelFont", w = sizeX/4-2, align="left")
NumberCheck = cmds.radioButtonGrp(labelArray2=[ '按数字', '按字母'], numberOfRadioButtons=2, w=sizeX, h=20, sl=1, cw = ([1,120]))
#ButtonRename and Number
cmds.separator(h=5, style = "none", parent = mainLayout)
cmds.button(label = "重命名并排序", w=sizeX, h=25, c=RenameNumber, align = "Center", parent = mainLayout)
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#RemoveCharacter
#Remove First/Last
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 25), (2, 60)], cs = [(5,5)])
cmds.text(label=" 删除:", font = "boldLabelFont", w = sizeX/3-12, align="left")
cmds.button(label = "第一个字符->", w=sizeX/3, h=25, c=lambda x: Remove(True), align = "Center")
cmds.button(label = "<-最后的字符", w=sizeX/3, h=25, c=lambda x: Remove(False), align = "Center")
cmds.separator(h=5, style = "none", parent = mainLayout)
#Remove pasted__
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 25), (2, 60)], cs = [(90,90)])
cmds.text(label="del pasted all", font = "boldLabelFont", w = sizeX/3-12, align="left")
cmds.button(label = "pasted__", w=50, h=25, c=RemovePasted,)
#Remove UI
cmds.separator(h=5, style = "none", parent = mainLayout)
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 25), (2, 60)], cs = [(8.5,8.5)])
RemoveFirst = cmds.textField(w = sizeX/5, tx="0", ann="Write the amount of characters you want to delete on text beginning")
cmds.button(label = "-", w=25, h=25, c=lambda x: RemoveChar('begin'), align = "Center", ann="Delete on text beginning")
cmds.button(label = "删除", w=sizeX/4, h=25, c=lambda x: RemoveChar('all'), align = "Center", ann="删除0-n自定义的字符")
cmds.button(label = "-", w=25, h=25, c=lambda x: RemoveChar('end'), align = "Center", ann="Delete on text ending")
RemoveEnd = cmds.textField(w = sizeX/5, tx="3", ann="Write the amount of characters you want to delete on text ending")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Suffix
#Control Suffix
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 前缀:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the prefix")
PrefixText = cmds.textField(w = sizeX/2.5+33, tx="prefix_", ann="Write the prefix")
cmds.button(label = "Add", w=sizeX/4-10, h=25, c=lambda x: PrefixSuffix(False), align = "Center")
cmds.separator(h=5, style = "none", parent = mainLayout)
#Group Suffix
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 后缀:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the suffix")
SuffixText = cmds.textField(w = sizeX/2.5+33, tx="_suffix", ann="Write the suffix")
cmds.button(label = "Add", w=sizeX/4-10, h=25, c=lambda x: PrefixSuffix(True), align = "Center")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Prefix
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.button(label = "SM_", w=sizeX/5-4, h=25, c=lambda x: Prefix('SM_'), align = "Center", ann = "Add SM_ Prefix")
cmds.button(label = "UCX_", w=sizeX/5-4, h=25, c=lambda x: Prefix('UCX_'), align = "Center", ann = "Add SM_ Prefix")
cmds.button(label = "_low", w=sizeX/5-4, h=25, c=lambda x: Suffix('_low'), align = "Center", ann = "Add _low suffix")
cmds.button(label = "_high", w=sizeX/5-4, h=25, c=lambda x: Suffix('_high'), align = "Center", ann = "Add _high suffix")
cmds.button(label = "_old", w=sizeX/5-4, h=25, c=lambda x: Suffix('_old'), align = "Center", ann = "Add _old suffix")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Custom
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label="组:", font = "boldLabelFont", w=20, h=25, align="left", ann="Write the text to search")
cmds.button(label = "Baking", w=60, h=25, c=lambda x: toGroup('Baking'), align = "Center", ann = "replace Baking")
cmds.button(label = "Collision", w=60, h=25, c=lambda x: toGroup('Collision'), align = "Center", ann = "replace Collision")
cmds.button(label = "Reference", w=60, h=25, c=lambda x: toGroup('Reference'), align = "Center", ann = "replace Reference")
cmds.separator(w = sizeX, h=15, style = "in", parent = mainLayout)
#Search and Replace
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 搜索:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the text to search")
SearchText = cmds.textField(w = sizeX/2+100, ann="Write the text to search")
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text(label=" 替换:", font = "boldLabelFont", w = sizeX/4-10, align="left", ann="Write the text to replace")
ReplaceText = cmds.textField(w = sizeX/2+100, ann="Write the text to replace")
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
SRCheck = cmds.radioButtonGrp(labelArray3=[ '选择', '层级', 'All'], numberOfRadioButtons=3, w=sizeX, h=20, sl=1, cw = ([1,95],[2,95],[3,95]))
cmds.button(label = "Apply", w=sizeX, h=25, c=SearchReplace, align = "Center", parent = mainLayout)
cmds.separator(h=5, style = "none", parent = mainLayout)
#miaomiao
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text("P._( :> )_")
cmds.rowColumnLayout( numberOfRows=1, w=sizeX, parent=mainLayout, rowHeight=[(1, 20), (2, 60)], cs = [(5,5)])
cmds.text("Friends, hope you can be happy every day!")
#Show UI:
cmds.showWindow(igEzRenamWin)
def SelectAll(*args):
cmds.select(ado=True, hi = True)
selection = cmds.ls(selection=True, sn=True)
selectionAdd = []
#Old select all code version
"""for objs in selection:
children = cmds.listRelatives(objs, c=True, f =True)
print "Children01:", children
shapes = cmds.listRelatives(objs, s=True, f = True)
print "Shapes:", shapes
if not children == None:
if not shapes == None:
for s in shapes:
children.remove(s)
for chi in children:
children2 = cmds.listRelatives(chi, c=True, f = True)
print "CHildren02:", children2
if not children2 == None:
for chi2 in children2:
children.append(chi2)
selectionAdd.append(chi)
for objs in selectionAdd:
cmds.select(objs, add=True)"""
def SelectName(*args):
cmds.select(cl=True)
name = cmds.textField(SelectName, text = 1, q=True)
try:
selection = cmds.ls(name, l = True)
except:
cmds.warning("Object Don't Exist")
for objs in selection:
cmds.select(objs, add=True)
def RenameNumber(*args):
number = cmds.textField(StartValue, text = 1, q=True)
number = int(number)
padding = cmds.textField(PaddingValue, text = 1, q=True)
padding = int(padding)
NumberLetters = cmds.radioButtonGrp(NumberCheck, q=True, select=True)
newName = cmds.textField(RenameText, text = 1, q=True)
selection = cmds.ls(selection=True, sn=True)
lettersList = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
#Number suffix
y = 0
for obj in selection:
try:
#Teste if has duplicate mesh with the same name on the scene and return the name without parents
trueName = testDuplicateName(obj)
#Save the original name
oldName = trueName
#If true use numbers, else use letters
if NumberLetters == 1:
zeros = ""
for x in range(int(padding)): # 使用 range 替代 xrange
if len(str(number)) <= x:
zeros = zeros+"0"
#Create the newName and rename
name = newName+"_"+"{:0>"+str(padding)+"}"
newNameList = name.format(number)
cmds.rename(obj, name.format(number))
else:
newNameList = newName+"_"+lettersList[y]
cmds.rename(obj, newName+"_"+lettersList[y])
if y < len(lettersList)-1:
y+=1
else:
y=0
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, newNameList)
selection[x] = newParentName
except:
pass
number = int(number+1)
def RemoveChar(Type):
first = cmds.textField(RemoveFirst, text = 1, q=True)
end = cmds.textField(RemoveEnd, text = 1, q=True)
selection = cmds.ls(selection = True, sn=True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
if Type == "all":
name = trueName[:-int(end)]
name = name[int(first):]
if Type == "begin":
name = trueName[int(first):]
if Type == "end":
name = trueName[:-int(end)]
try:
cmds.rename(objs, str(name))
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, name)
selection[x] = newParentName
def Remove(Type):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
if Type:
name = trueName[1:]
else:
name = trueName[:-1]
try:
cmds.rename(objs, name)
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, name)
selection[x] = newParentName
def RemovePasted(*args):
selection = cmds.ls("pasted__*", long=True)
if not selection:
cmds.warning("没有找到以 'pasted__' 开头的对象。")
return
for obj in selection:
# 获取对象的短名称
short_name = obj.split("|")[-1]
# 移除 "pasted__" 前缀
new_name = short_name[8:]
try:
cmds.rename(obj, new_name)
print(f"已重命名: {obj} -> {new_name}")
except Exception as e:
cmds.warning(f"重命名 {obj} 时出错: {str(e)}")
cmds.select(clear=True)
cmds.select(selection)
cmds.warning(f"已处理 {len(selection)} 个对象。")
def PrefixSuffix(Suffix):
prefix = cmds.textField(PrefixText, text = 1, q=True)
suffix = cmds.textField(SuffixText, text = 1, q=True)
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
if Suffix:
name = str(trueName)+suffix
else:
name = prefix+str(trueName)
try:
cmds.rename(objs, name)
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, name)
selection[x] = newParentName
#add Suffix
def Suffix(Text):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
newName = trueName+Text
try:
cmds.rename(objs, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
#add prefix
def Prefix(Text):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
newName = Text+trueName
try:
cmds.rename(objs, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
#Custom
def Custom(Text):
selection = cmds.ls(selection = True, sn = True)
for objs in selection:
#Teste if has duplicate mesh with the same name on the scene
trueName = testDuplicateName(objs)
#Save the original name
oldName = trueName
newName = Text
try:
cmds.rename(objs, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
#toGroup
def toGroup(Text):
selection = cmds.ls(selection = True, sn = True)
cmds.group(selection, n=Text)
def SearchReplace(*args):
search = cmds.textField(SearchText, text = 1, q=True)
replace = cmds.textField(ReplaceText, text = 1, q=True)
SRMethod = cmds.radioButtonGrp(SRCheck, q=True, select=True)
#Selected search and Replace method
if SRMethod == 1:
selection = cmds.ls(selection = True, sn = True)
#Hierarchy search and Replace method
if SRMethod == 2:
cmds.select(hi = True)
selection = cmds.ls(selection = True, sn = False)
#All search and Replace method
if SRMethod == 3:
#Select All DagObjects in scene
selection = []
cmds.select(ado = True, hi = True)
selection = cmds.ls(selection = True, sn=False)
#for to rename the objects
for obj in selection:
#Teste if has duplicate mesh with the same name on the scene and return the name without parents
trueName = testDuplicateName(obj)
#Save the original name
oldName = trueName
#Search and replace to create the new name
newName = trueName.replace(search, replace)
#Rename the object
try:
cmds.rename(obj, newName)
except:
pass
#For to rename all the oldNames on list to newNames
for x in range(len(selection)): # 使用 range 替代 xrange
newParentName = selection[x].replace(oldName, newName)
selection[x] = newParentName
print("Selection: ", selection) # 修正拼写错误
def testDuplicateName(Obj):
try:
trueName = Obj.split("|")
return trueName[len(trueName)-1]
except:
return Obj
收费不错的工具
Ninjin Normals | 可爱风顶点法线编辑工具
只支持 maya2023及以上 python3制作
自带预览shader,可查看卡通阴影和风格化渲染