stp格式文件导入3ds Max MaxScript批处理工具

〇、说明
0.除自定义脚本,其余示例摘自3DS MAX 2017 Help
1.将乱码部分统一命名,调整规则如下;
a.mesh节点:如果mesh乱码,其父物体命名正确,则将其命名为与父物体同名;
b.对于所有节点,如果名称中含有"|:|",则截取第一个"|“前的字符作为名称,否则,删除名称中的非法字符,作为名称(第一个”|“前的字符相同的mesh多为同一对象,第二个”|“的猜测为类似索引值的标记),如果首字符为”_",则添加"Object"前缀(主要因为此种情况下经删除非法字符后保留的字符较少);
2.将指定文件夹下所有stp逐个导入到3ds Max并分别在各自路径下导出为fbx;
3.调整每个对象的缩放值(1,1,1)和轴心点(位于物体的中心);
4.删除同一虚拟节点下重复的Mesh(尚存问题,已弃用);
a.如果两个mesh中的一个是另一个的冗余部分,则删除顶点较少的mesh对象;
b.如果两个mesh是不同的对象,则保留;
c.以上判断通过两个mesh的center的点积进行判断的(尚存问题);
一、MaxScript
1.StpModelCovertToFbxTool

global validChar="_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

fn filteringInvalidChar instring =-- beginning of function definition
( local outstring-- declare variables as local
-- create an unique copy of the string referenced by instring,
-- and store reference to unique copy in outstring
-- set variables to literals

	result =""
	outstring=copy instring
 
-- increment from 1 to number of character in string
	for i=1 to outstring.count do(
-- see if the single character at index i in outstring
-- is present instring lower
-- If so, j equals position in string validChar.
-- If not, j equals undefined
        a=findstring validChar outstring[i]

        if a!=undefined then
			result+=outstring[i]
		else result
        
-- value will be returned as function result
	)
	result
)



fn getFilesRecursive root pattern =
(
	dir_array = GetDirectories (root+"/*")
	for d in dir_array do
		join dir_array (GetDirectories (d+"/*"))
	my_files = #()
	for f in dir_array do
	join my_files (getFiles (f + pattern))
	my_files
)

fn correctGeometryName =(
	for obj in geometry do(
		splitName=filterString  obj.name "|"
		if splitName.count>1 then
			obj.name=splitName[1]
	
		else(for i=1 to obj.name.count do(		
			if obj.name[i]!=undefined do(		
				b=findstring validChar obj.name[i]
				if b==undefined do
					obj.name=obj.parent.name
			)		
		)	
		)
	)
)

fn correctNodeName =(
	i=0
	for obj in objects do(
		rightname=filteringInvalidChar obj.name as string
				
		if rightname.count>1 then
			obj.name=rightname
		else (
			obj.name="Target"+i as string
			i+=1
		)
			
		if obj.name[1]=="_" do
			obj.name="Object"+obj.name
		)
)


fn resetModel=(
	for obj in objects do(
	CenterPivot obj
	ResetScale  obj
	ResetTransform obj
	) 
)
#尚存问题
fn deleteRepeatedModel=(
	for obj in geometry do(
		if obj.parent.children.count>=2 do(
			if (dot obj.parent.children[1].center obj.parent.children[2].center<30)  do(

				try(
					if obj.parent.children[1].verts.count  <obj.parent.children[2].verts.count then
						delete obj.parent.children[1]
					else 
						delete obj.parent.children[2]
				)
				catch ()
			)
		)
	)
)



stpModelPath="E:\Unity Arts Assets\3ds Max\Schneider Pan Gu"
--stp原始模型路径

dir_array = getFilesRecursive stpModelPath "*stp"

print dir_array.count as string
for	i=1 to dir_array.count do(
	print dir_array[i]
)


for d in dir_array do(	
	for	f in getfiles d do(
		loadmaxfile f
		
		correctGeometryName()
		correctNodeName()
		resetModel()
		#deleteRepeatedModel()
		
		fname=(filterString(pathConfig.stripPathToLeaf d) ".")[1]+".fbx"
		exportfile (pathConfig.removePathLeaf d+"\\"+fname) #noprompt selectedonly:false using:fbxexp
	)
)

2.WriteAllStpMoldelPathToTxt

fn format_txt filepath filetext =
(
    if doesFileExist filepath == true 
        then
    (
        fin = openfile filepath mode:"r+"
        seek fin #eof
        txt = filetext + "\n"
        format txt to:fin
        close fin
    )
    else
    (
        newfile = createFile filepath
        close newfile
        format_txt filepath filetext
	)
)


stpModelPath="E:\3ds Max\Stp Models"
--stp原始模型路径

txtPath="E:\Unity Arts Assets\3ds Max\Schneider Pan Gu\StpList.txt"


dir_array = getFilesRecursive stpModelPath "*.stp"

for	i=1 to dir_array.count do(
	format_txt txtPath dir_array[i] as string
)

3.findString

<integer>findString<string> <search_string>
Returns the index of search_string in string or undefined if not found.

EXAMPLE

findString "Thanks for all the fish!" "all" -- returns 12 

4.The following script shows the use of various literals, constructors, properties, operators, and methods of the String class.
EXAMPLE

-- strings test bed
fn uppercase instring =-- beginning of function definition
( local upper, lower, outstring-- declare variables as local
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"-- set variables to literals
lower="abcdefghijklmnopqrstuvwxyz"
 
-- create an unique copy of the string referenced by instring,
-- and store reference to unique copy in outstring
outstring=copy instring
 
-- increment from 1 to number of character in string
for i=1 to outstring.count do
 
-- see if the single character at index i in outstring
-- is present instring lower
-- If so, j equals position in string lower.
-- If not, j equals undefined
( j=findString lower outstring[i]
 
-- if character was found in lower,
-- replace with corresponding character in upper:
if (j != undefined) do outstring[i]=upper[j]
)
outstring-- value will be returned as function result
)-- end of fn uppercase
 
s1="AbCdEfGh"-- set variable to literal
s2=uppercase s1-- call function uppercase, passing s1 as parameter
if s1 == s2 do print "strings s2 and s3 are the same"-- compare strings
if s1 != s2 do print "strings s1 and s2 are different"
 
theObject="sphere"-- set variable to literal
theRadius= (random 10. 100.) as string-- convert number to string
-- concatenate strings and execute string
myObject=execute (theObject +" radius:"+ theRadius)

OUTPUT:

uppercase()-- result to function definition
"AbCdEfGh"-- result of line 24
"ABCDEFGH"-- result of line 25
undefined-- result of line 26 - stringsnot equal,
-- and no else expression in if expression
"strings s1 and s2 are different"-- output from line 27
"strings s1 and s2 are different"-- result of line 27
"sphere"-- result of line 29
"75.4091"-- result of line 30
$Sphere:Sphere001 @ [0.000000,0.000000,0.000000]-- result of line 32. Execute function
-- created a sphere object 

5.getFiles

getFiles <wild_card_filename_string> 	 

Returns an array of file names that match the given wild-card path name.

FOR EXAMPLE,

The following code gets an array of all the .max scene files in c:\foo and then loops over the array, opening each file and printing the objects in each:

files = getFiles "c:\\foo\\*.max"
for f in files do (loadMAXFile f; print objects)

getFiles() can also be used to determine if a file or file pattern exists.

FOR EXAMPLE

the following function will return true if the specified file name or pattern exists:

fn existFile fname = (getfiles fname).count != 0

See also doesFileExist() which checks for a single file only and does not supportwildcardpatterns.

6.getDirectories

Returns an array of directory paths that match the given wild-card directory path name.

SCRIPT

fn getFilesRecursive root pattern =
(
dir_array = GetDirectories (root+"/*")
for d in dir_array do
  join dir_array (GetDirectories (d+"/*"))
my_files = #()
for f in dir_array do
  join my_files (getFiles (f + pattern))
my_files
)
--get all .ms files from the folder c:/temp
--and all its subfolders:
getFilesRecursive "c:/temp" "*.ms"

7.filterString

<array of strings>filterString <string> <token_string> [splitEmptyTokens:<boolean>]

Parses string based on token_string and returns an array of strings. The filterString splits the input string into substrings based on the characters given in token_string , and returns each substring as a member of the array. The token_string is simply a list of ‘splitter characters’ (when the string is scanned, any occurrence of any of the tokens is regarded as the start of a substring). This function is useful for file import/export scripts or for any type of manual parsing.

FOR EXAMPLE

filterString "MAX Script, is-dead-funky" ", -"

WOULD RETURN

#("MAX","Script","is","dead","funky")

If splitEmptyTokens is false or not specified, sequential tokens are handled as a single token and tokens at the beginning or end of the string are ignored. If splitEmptyTokens is true , each token found will result in string element in the output, with the string element in the cases ignored above being empty strings

8.pathConfig.removePathLeaf

pathConfig.removePathLeaf <path> 

Removes a leaf from the given path.

FOR EXAMPLE,

pathConfig.removePathLeaf "c:\\temp\\test"
"c:\temp"

pathConfig.stripPathToLeaf

9.pathConfig.stripPathToLeaf <path_or_filename> 

Returns the last sub-directory name from the given path. If the path is a full file name, returns the file name. Equivalent to filename from path.

EXAMPLES:

pathConfig.stripPathToLeaf "C:\\temp\\test"
"test"
pathConfig.stripPathToLeaf "C:\\temp\\test\\"
""
pathConfig.stripPathToLeaf "C:\\temp\\test\\somefile.tga"
"somefile.tga"
--COMPARE:
filenamefrompath "C:\\temp\\test"
"test"
filenamefrompath "C:\\temp\\test\\"
""
filenamefrompath "C:\\temp\\test\\somefile.tga"
"somefile.tga"

10.CenterPivot

CenterPivot <node>-- mapped method

Same as Hierarchy/Pivot/Affect Pivot Only - Center to Object.

11.ResetScale

ResetScale <node>-- mapped method 

Same as Hierarchy/Pivot/Reset Scale.
Vector Dot Product

12.dot

dot <point3> <point3>

Returns the vector dot product.

The geometric interpretation of the dot product is the length of the projection of the first vector onto the unit vector of the second vector. Obviously, when the two vectors are perpendicular, the dot product is 0.0.

The dot product is commutative, which means that dot X Y == dot Y X.

The dot product is associative, which means that dot (rX) Y == r(dot X Y).

The dot product is distributive, which means that dot X (Y+Z) == (dot X Y) + (dot X Z).

Because the dot product of two normal vectors is the cosine of the angle between them, the dot product can be used conveniently to calculate the angle between two vectors:

FOR EXAMPLE

fn GetVectorsAngle v1 v2 =
(
	theAngle = acos(dot (normalize v1) (normalize v2))
)

GetVectorsAngle [10,0,0] [10,20,0]
63.435

13.Try Expression
Try Expression

你可能感兴趣的:(专业软件,3dsmax)