• Maxscript 使用依赖注入的模式来设计材质转换工具概要


    需求

    在常规的转换工具编写中,我们需要编写材质的转换代码,编写后需要进行注册到类型判断中
    比如,把标准材质转换到vray材质,我们可能会这样写

    fn convertStandardToVrayMtl oldMat =
    (
          newMat = VrayMtl()
          return newMat
    )
    --使用时进行类型判断,这里我管他叫注册
    if classof xx == Standard do 
          obj.mat = convertStandardToVrayMtl xx
    
    

    如果添加了新的转换函数,我们又需要加入到类型的注册中,很多设计模式也是这样,编写函数 --> 注册类型 --> 使用函数
    但由于材质类型众多,代码量会变得很长,多一步注册或者忘记注册是烦人的事情
    于是乎,在其他语言中常见的控制反转模式,拿到这里来应该非常好用,而且转换函数的模式非常固定,传入旧实例,返回新实例,非常适合做模板式的代码编写

    容器处理

    mxs的结构类型中,可以使用 getPropNames 来获得一个结构体的成员名字,以此来实现其他语言的"反射"特性

    struct foo
    (
    	age,
    	showMyAge = fn _ myName = (print (myName + " - " + this.age as string)),
    	fn eat =
    	(
    		print 1
    	)
    )
    newFoo = foo()
    
    --获取所有方法以及属性名字
    getPropNames newFoo --返回 #(#age, #test, #showMyAge)
    
    --通过名字找到方法
    eatFn = getProperty newFoo #eat
    --调用方法
    eatFn()
    
    --重写方法,因为showMyAge作为一个<data>,而非一个函数,所以他的内容可以被赋予任何内容
    --如果你需要调用实例内的成员,这里的this作为一个很丑陋的形参
    newFoo.showMyAge = (fn _ myName this = (
    	this.age = 50
    	print (myName + " -- " + this.age as string)
    ))
    --调用方法
    newFoo.showMyAge "tom" newFoo 
    
    --还有一个需求,mxs里面没有继承,我们无法为原有结构添加新的处理函数,比如新版更新了有了新的材质类型
    --可以定义一个扩展数组成员,为未来新添加的处理函数预留位置
    

    转换函数

    有了上面的容器处理方法,就可以编写转换函数了,为了便于容器处理时使用 getPropNames 的方式找到处理的函数,这里对函数的名字进行强制规定
    使用ConvertFromMat前缀开头,下划线分割,结尾接具体的材质类型,参数为旧材质,返回类型为新材质
    在处理容器中直接分割函数名字可以非常轻松的拿到:需要转换的材质类型,从而实现自动化处理,无需手动注册,我们仅仅需要专注转换函数的编写,其他由框架自动处理
    比如:

    --将标准材质转为Vray材质
    fn ConvertFromMat_Standardmaterial oldMat = 
    (
          ...
          return newMat
    )
    --为了方便整体的替换,所有输入得参数变量名全部改为old ,输出变量名为r
    

    其他

    为了兼容汉化属性

    我还专门搞了个工具来进行痛苦的替换,越陷越坑发现这个是大工程

  • 相关阅读:
    VC CComboBox用法总结
    WideCharToMultiByte和MultiByteToWideChar函数的用法
    JavaScript
    标题:外星日历
    C语言顺序栈
    C语言循环队列
    每日一题
    标题:李白打酒
    标题:分数
    标题:复数幂
  • 原文地址:https://www.cnblogs.com/trykle/p/13734644.html
Copyright © 2020-2023  润新知