maxscript与dotnet交互扩展,字典,小数保留,字符串,时间,guid等

记录一些常见的随手就用的代码片段

字典

dict = dotNetObject "System.Collections.Generic.Dictionary`2[System.String,System.String]"
dict.Remove "trykle_name"
dict.Add "trykle_name" "123"
dict.Add "trykle_age" "456"
dict.ContainsKey "trykle_name"
dict.ContainsValue "123"
dict.Clear()

--从Key取值
dict.Item["trykle_name"]

--遍历
it = dict.GetEnumerator()
while it.MoveNext() do
(
	key = it.current.key 
	val = it.current.value
	print (key + " " + val)
)

mxs与dotnet的数据转换

  • 将max对象包装成dotNetMXSValue 传给.net的Object类型送入字典
dict = dotNetObject "System.Collections.Generic.Dictionary`2[System.String,System.Object]"
dict.Remove "trykle_objs"
dict.Add "trykle_objs" (dotNetMXSValue (#($Teapot001, $Teapot002)))
--从Key取值
dict.Item["trykle_objs"].value
  • 数据的转换
    将mxs对象转换为dotnet对象
    此方法用于对接确定类型值
dict = dotNetObject "System.Collections.Generic.Dictionary`2[System.String,System.String[]]"
dict.Remove "trykle_pathes"
files = dotnet.ValueToDotNetObject #("path1.txt", "path2.txt") (dotNetClass "System.String[]")
dict.Add "trykle_pathes" files
--从Key取值
dict.Item["trykle_pathes"]

NameValueCollection

--可叠加写
nvc= dotNetObject "System.Collections.Specialized.NameValueCollection"
nvc.Add "trykle_red" "1" --叠加写 ,一个key多个value,可重复
nvc.Set "trykle_red" "2" -- 覆盖写,只留最新一个

nvc.Clear()

-- 检测是否有key
-- 获取key的数组
if nvc.GetValues "trykle_red" == undefined do
(
	print "不存在这个值"
)

--取值
nvc.Count
nvc.Item[1]
nvc.Item["trykle_red"]
nvc.AllKeys
nvc.Keys

--遍历取值
for i = 1 to nvc.AllKeys.Count do
(
	key = nvc.AllKeys[i]
	vals = nvc.GetValues key --这个返回的是一个数组
	print (key + " - " + vals [1])
)

数字操作

--四舍五入
num = 1.34852
dnDouble = dotnet.ValueToDotNetObject num (dotNetClass "System.Double")
res = (dotnetclass "System.Math").round dnDouble 2
res as float -- 1.35

--数字位数对齐
num = 15
dnInt = dotnetobject "System.Int32" num
dnInt.ToString "D3"  --015

--小数位数
num = 15.1
dnDec = dotnetobject "System.Decimal" num
dnDec.ToString "0.00" -- "15.10"

读写文件

str = (dotNetClass "System.IO.File").ReadAllText @"C:\trykle\1.txt"

encoding = (dotNetClass "System.Text.Encoding").GetEncoding "utf-8"
encoding = (dotNetClass "System.Text.Encoding").GetEncoding "gb2312"
(dotNetClass "System.IO.File").WriteAllText @"C:\trykle\1.txt" "这是写入的字符串内容" encoding 

目录

--获取系统目录
docDir = (dotNetClass "System.Environment").GetFolderPath((dotNetClass "System.Environment+SpecialFolder")).MyDocuments

--获取上级目录
parent = (DotnetObject "System.IO.DirectoryInfo" docDir).Parent.FullName 

--2012没有 doesDirectoryExist 这个函数
--检测文件夹是否存在 
(dotnetclass "System.IO.Directory").Exists

--检测文件是否存在 
(dotnetclass "System.IO.File").Exists 

--获取文件夹名字 
 ((DotnetObject "System.IO.DirectoryInfo" @"C:\trykle\video").Name)

文件路径获取函数重写

max自带的函数对包含$字符的路径有特殊癖好

,fn getFilenamePath str =
(
	p = (dotNetClass "System.IO.Path").GetDirectoryName str
	return (p + "\\")
)
,fn getFilenameFile str =
(
	p = (dotNetClass "System.IO.Path").GetFileNameWithoutExtension str
	return (p)
)
,fn getFilenameType str =
(
	p = (dotNetClass "System.IO.Path").GetExtension str
	return (p)
)

时间

--格式化时间
(dotnetclass "System.DateTime").Now.ToString "yyyyMMddHH mmss ffffff"

--时间差
startTime = (dotNetClass "System.DateTime").Now
max quick render
endTime = (dotNetClass "System.DateTime").Now
ts = endTime.Subtract startTime
usedSeconds= ts.TotalSeconds as float
format "用时%秒\r\n" usedSeconds

Guid

id = ((dotNetClass "System.Guid").NewGuid()).ToString "N"
shortId = substring id 1 12

加载dll

--静态加载
dotnet.loadAssembly @"C:\Program Files\Autodesk\3ds Max 2014\MaxCustomControls.dll"
dotnetclass "MaxCustomControls.MaxUserControl"

--动态加载
dllFile = @"D:\trykle\mydll.dll"
asm = (dotnetClass "System.Reflection.Assembly").Load ((dotnetClass "System.IO.File").ReadAllBytes dllFile)
--创建类实例
cls = asm.createInstance "NS.Cls"
--调用类方法
cls.YourMethod()

字符串

--字符串连接
separator = "-"
strArr = #("1", "2", "3")
newStr = (dotNetClass "System.String").Join separator strArr
--"1-2-3"

--颜色转16进制
cor = color 231 24 161
hexR = (dotNetClass "System.Convert").ToString cor.r 16
hexG = (dotNetClass "System.Convert").ToString cor.g 16
hexB = (dotNetClass "System.Convert").ToString cor.b 16
hexCor = "#" + hexR + hexG + hexB

动态编译c#代码

注意此方法会被诺顿等杀软进行默认拦截,不管GenerateInMemory是否设置为true都将视为命令行编译到本地文件行为

global TrykleCsTestClass
fn initTrykleCsTestClass =
(
	local source = "
	using System;
	using System.Windows.Forms;

	public class TrykleCsTestClass
	{ 
		public static int TestMethod(string msg)
		{
			MessageBox.Show(msg);
			return 1;
		}
	}
	"	
	local csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
	compilerParams.ReferencedAssemblies.Add("System.dll")
	compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
	compilerParams.GenerateInMemory = on
	local compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
	
	if (compilerResults.Errors.Count > 0) then
	(
		local errs = stringstream ""
		for i = 0 to (compilerResults.Errors.Count-1) do
		(
			local err = compilerResults.Errors.Item[i]
			format "编译时出现错误:% Line:% Column:% %\n" err.ErrorNumber err.Line err.Column err.ErrorText to:errs
		)
		format "%\n" errs
		undefined
	)
	else
	(
		local asm = compilerResults.CompiledAssembly.CreateInstance "TrykleCsTestClass"	
		--此处实例化类,一般使用此方法都是代码已经在vs中测试好的情况,所以不需要动态反射创建
		TrykleCsTestClass = dotNetObject "TrykleCsTestClass"
	)
)

if classof TrykleCsTestClass != dotNetObject do
(
	print "初始化类编译"
	initTrykleCsTestClass()
)

if classof TrykleCsTestClass == dotNetObject do
(
	print "可以正常调用类"
	TrykleCsTestClass.TestMethod "你好"
)

多线程

用于操作与max对象无关的事情

global isCancel = false

fn fooFunc =
(
	while true do
	( 
		(dotNetClass "System.Threading.Thread").Sleep 1000
		--退出
		if isCancel == true then
		(
			exit
		)
		--
		print ((dotnetclass "System.DateTime").Now.ToString "yyyy/MM/dd HH:mm:ss")
	)

)
--global BackgroundWorker = DotNetObject "System.ComponentModel.BackgroundWorker"
global BackgroundWorker = DotNetObject "CSharpUtilities.SynchronizingBackgroundWorker"
DotNet.AddEventHandler BackgroundWorker "DoWork" fooFunc  
BackgroundWorker.WorkerSupportsCancellation = true 
BackgroundWorker.RunWorkerAsync()
posted @ 2023-11-15 14:37  trykle  阅读(36)  评论(0编辑  收藏  举报