签到

06月02日
尚未签到

共有回帖数 0

    回望空城

    等级:
    吧里都是各种建模和渲染大神,本人美术功底不行,渲染又不会。从事了几年游戏美工,自学了一些MAX的脚本语言,现来分享一些简单实用的功能
    MaxScript 语法有些类似C++ 但是比C++要更高级,更方便。
    废话不多。。。
    首先是如何打开脚本窗口

    左边的叫做Linstener窗口,用于运行单行程序以及给出反馈,一般用来测试代码。
    右边的就是编辑窗口,可以运行一整套代码。




    由于这里基本都不是学编程的,所以我也不会像教编程一样,按套路来。
    还是总结一些新手比较多见的问题。






    2.数学运算和逻辑运算


    max的Listener窗口,还能进行一些数学运算。
    比如 整数运算 50 + 50 对应输入100
    sin 90度 结果为 1
    反三角函数 asin 0.5的结果 则为30度
    50的倒数为0.02
    圆周率在max中 为 3.14159


    接下来的3个 5/2是脚本中比较容易弄错的。
    在计算机语言中 分 整数和浮点数两种不同的数字类型。
    5除以2 被计算机认为整数运算 所以 5/2在日常生活中,答案为2.5,但是由于计算机默认成整数运算,所以会把小数部分忽略,所以返回的结果 就是2 (没有4舍5入)
    下来的5.和5.0其实是一样的,计算机语言中 整数后跟小数点,就会被认为是浮点数,不需要再写成5.0。
    之后 浮点数 与 整数进行运算,输出结果也为浮点数。 所以5.0/2结果为2.5
    BTW:0和1之间的数字 也可以输入为 .x(x为数字) 而不用输入成 0.x


    接下来 x = 1
    很容易理解,就是 定义一个变量 x,x的值为1
    所以返回结果为1


    接下来x == 2
    两个等号 为比较运算符(逻辑运算符的一种),可以理解为 x的值和2对比 如果相同,则返回true,如果不同,则返回false
    可以看到 x == 2返回的是false 而 x == 1返回的true
    还有其他的比较运算符 比如 (大于) , (小于) , =(大于或等于) , =(小于或等于) , !=(不等于 注意 感叹号 记作 非 运算符 也就是 not)


    这是 for 循环的一个概念。 i 是一个变量,可以记成任何名称,比如 你可以改成 index 改成 object 改成 a 改成 b 都可以。。1 to 10代表 从1开始到10的数字(包括 1和10),


    第一条中 我从1 循环到 物体的数量 每循环一次 就会 定义三个随机数 代表 r g b 红 绿 蓝 3个颜色 分别从 0 到 255(涉及到计算机图形知识,不详细解释)
    random是一个max自带函数 需要2个数字作为参数 分别是上限和下限,用空格隔开 所以 记作 random 0 255 就是随机从0到255(包括)中的任意数字


    接下来 selection

    selection为当前选择集,其作用和$类似,具体区别,不太清楚(selection返回的是一个集合,都记作$selection 。$在选中单个物体时,会返回这个物体的属性)。。写作$也可以运作。
    后面的表示选择集中 第 i 个物体 所以 selection[1]就表示为 该选择集中,排名第一个的物体。 之后 括号内的操作 都是针对这个物体,当全部执行完后,i会增加1 一直循环到 最后一个物体。
    之后 wirecolor 为 物体的线框颜色(注意,如果有材质球,线框颜色不会影响到物体表面颜色。)
    之后 (color r g b)

    color 也是一个max自带函数 需要 红 绿 蓝 三种数值,分辨为 0到255的数字
    3.续


    第二种方法更为简单粗暴
    直接将 i(stand for "index" index的首字母,其实 这里 i 改成 o(object)命名更合理 who care...) 定义为选择的物体
    由于 i 本身就是一个物体变量, 所以 不需要再通过索引的数字来循环物体。
    所以 i.wirecolor 直接就是 当前物体的线框颜色


    这次,我选择 在 geometry中进行挑选 geometry是几何体的英语,这样的操作,目的在于不会选中场景中的虚拟体,灯光,摄像机等非几何体。
    where则是类似一个筛选的命令 在几何题中 只选择 transform中scale(transform有三项,分别为位移,旋转和缩放)。我只选择缩放属性有改变(不为[1,1,1]分别对应 x y z轴)
    由于我不需要对那些物体进行操作,只需要筛选出来,所以这里用到collect i 而不是之前的 do
    把选中的物体 加入到一个选择集中 我把这个集命名为c(collection)
    这样
    使用 select(选择)命令 选中选择集c 就可以把所有 带有缩放信息的物体挑选出来,单独进行x-form也行
    配合 for i in $ do i.scale = [1,1,1],把尺寸调回到原先也可以。


    在建模场景时,可能会有大量的重复复杂物体,会用到大量实例复制。
    有时候,都是先做完一个物体,再去复制出其他的。 但是这样会造成比例不好把握。
    现在提供一种反向思路,不如先把物体摆在那里,控制好比例,再去单独调整一个物体。
    最后 通过脚本 把没有修改过的模型与完成的模型进行关联。


    OK, Let's go


    我不打算在这里教如何制作UI, 所以 这里 提供纯代码教学,如果对Maxscript有兴趣的话,可以自行搜索如何制作UI。


    首先,定义为一个变量,让变量的值成为修改过的模型
    选中修改过的模型
    假设变量名为 x(源模型)
    x= $


    选中需要修改的模型
    $.baseobject = x


    。。忘记一个很重要的操作。。。。


    在编辑窗口中,写完代码,
    使用Ctrl+E进行全部执行
    Shift+Enter为执行当前选中行。。



    提供一个之前写的脚本。。。没什么特别的,都是功能性插件。
    需要基于算法的就不发出来了。BUG比较多。。


    使用方法,
    把所有代码复制到一个txt文件中,然后把txt后缀改成ms
    直接拖到max中 就可以使用,其中批量导入导出可能会因为版本问题有bug 我是基于2010编写的脚本,所以。。。


    有兴趣的欢迎讨论~~


    if myTools !=undefined do destroydialog mytools

    base = undefined
    file_path = maxfilepath
    export_op = exporterPlugin.classes
    t_obj = export_op[14]
    t_3ds = export_op[1]
    t_ascii = export_op[16]
    t_fbx = export_op[8]
    selectionarray = #()
    Fn getnames Title FilterName =
    (

    dialog = DotNetObject "System.Windows.Forms.OpenFileDialog"
    dialog.title = Title
    dialog.filter = FilterName
    dialog.Multiselect = true
    OpenFileResult = dialog.ShowDialog()
    if OpenFileResult.Equals OpenFileResult.OK then
    (
    dialog.FileNames
    )
    else Undefined
    )

    rollout myTools "My Tools" width:225 height:341
    (

    rollout imp_open "批量打开/导入" width:172 height:123
    (
    button open_max "MAX" pos:[11,90] width:148 height:24
    button imp_obj "OBJ" pos:[90,14] width:69 height:29
    button imp_3ds "3DS" pos:[11,51] width:69 height:29
    button imp_ase "ASE" pos:[90,51] width:69 height:29
    button imp_fbx "FBX" pos:[11,14] width:69 height:29
    on open_max pressed do
    (
    file_names = getnames "选择打开文件" "MAX (*.max)|*.max"

    if file_names != undefined do
    (
    for f in file_names do mergemaxfile f
    destroydialog imp_open
    )

    )
    on imp_obj pressed do
    (
    file_names = getnames "选择导入文件" "OBJ (*.obj)|*.obj"

    if file_names != undefined do
    (
    for f in file_names do importfile f #noprompt
    destroydialog imp_open
    )
    )
    on imp_3ds pressed do
    (
    file_names = getnames "选择导入文件" "3DS (*.3ds)|*.3ds"

    if file_names != undefined do
    (
    for f in file_names do importfile f #noprompt
    destroydialog imp_open
    )
    )
    on imp_ase pressed do
    (
    file_names = getnames "选择导入文件" "ASE (*.ase)|*.ase"

    if file_names != undefined do
    (
    for f in file_names do importfile f #noprompt
    destroydialog imp_open
    )
    )
    on imp_fbx pressed do
    (
    file_names = getnames "选择导入文件" "FBX (*.fbx)|*.fbx"

    if file_names != undefined do
    (
    for f in file_names do importfile f #noprompt
    destroydialog imp_open
    )
    )
    )


    下续

    rollout file_op "批量操作" width:175 height:128
    (
    button save_obj "批量MAX" pos:[91,47] width:70 height:67
    button op_obj "批量OBJ" pos:[91,12] width:70 height:32
    button op_3ds "批量3DS" pos:[11,47] width:70 height:32
    button op_ascii "批量ASCII" pos:[11,82] width:70 height:32
    button op_fbx "批量FBX" pos:[11,12] width:70 height:32
    on save_obj pressed do
    (
    if selection.count0 then
    (
    for i in selection do savenodes i (file_path + "\" + i.name + "single" + ".max")
    messagebox("保存完毕,路径为 " + file_path)
    destroydialog file_op
    )
    else messagebox"请选择物体以保存"
    )
    on op_obj pressed do
    (
    for i in 1 to selectionarray.count do
    (
    select selectionarray
    exportfile (file_path + "\" + selectionarray.name +".OBJ") #noprompt selectedonly:true using:t_obj
    )
    messagebox("导出完毕,路径为 " + file_path)
    destroydialog file_op
    shelllaunch "explorer.exe" file_path
    )
    on op_3ds pressed do
    (
    for i in 1 to selectionarray.count do
    (
    select selectionarray
    exportfile (file_path + "\" + selectionarray.name +".3DS") #noprompt selectedonly:true using:t_3ds
    )
    messagebox("导出完毕,路径为 " + file_path)
    destroydialog file_op
    shelllaunch "explorer.exe" file_path
    )
    on op_ascii pressed do
    (
    for i in 1 to selectionarray.count do
    (
    select selectionarray
    exportfile (file_path + "\" + selectionarray.name +".ASE") #noprompt selectedonly:true using:t_ascii
    )
    messagebox("导出完毕,路径为 " + file_path)
    destroydialog file_op
    shelllaunch "explorer.exe" file_path

    )
    on op_fbx pressed do
    (
    for i in 1 to selectionarray.count do
    (
    select selectionarray
    exportfile (file_path + "\" + selectionarray.name +".FBX") #noprompt selectedonly:true using:t_fbx
    )
    messagebox("导出完毕,路径为 " + file_path)
    destroydialog file_op
    shelllaunch "explorer.exe" file_path
    )
    )
    rollout instance_check "Instance" width:203 height:201
    (
    pickbutton btn26 "拾取" pos:[63,41] width:82 height:28
    GroupBox grp1 "拾取实例源对象" pos:[14,10] width:182 height:118
    button btn34 "实例化目标" pos:[35,146] width:129 height:29
    label lbl3 "源对象:" pos:[29,92] width:48 height:18
    label lbl4 " " pos:[81,90] width:103 height:25


    on btn26 picked pickobj do
    (

    base = pickobj
    lbl4.caption = base.name
    )
    on btn34 pressed do
    (

    if selection.count  0 and base != undefined then
    (
    $.baseobject = base.baseobject
    $.material = base.material
    )
    else messagebox"请选择需要被实例化的对象"
    )
    )
    button check_transform "检查变换" pos:[14,11] width:94 height:31
    button invselection "反向隐藏" pos:[14,53] width:94 height:31






    button btn10 "Rename" pos:[14,95] width:94 height:31
    button btn21 "Re_Instance" pos:[14,137] width:94 height:30
    button modifiers_on "开" pos:[24,190] width:34 height:20
    button delmod "删除修改器" pos:[14,218] width:94 height:31
    button saveobj "批量存储" pos:[14,257] width:94 height:31
    button import_but "批量导入" pos:[14,296] width:94 height:31
    button set_pivot "对齐轴心" pos:[118,11] width:94 height:31
    button WP_edit "Edit" pos:[123,64] width:41 height:20
    GroupBox workpivot_gup "工作轴" pos:[116,44] width:100 height:46
    button WP_use "Use" pos:[169,64] width:41 height:20
    button modifiers_off "关" pos:[64,190] width:34 height:20
    groupBox grp3 "修改器开关" pos:[16,172] width:91 height:41

    on myTools close do
    (
    destroydialog instance_check
    destroydialog file_op
    destroydialog imp_open
    )
    on check_transform pressed do
    (
    istrans = for o in objects where o.scale !=[1,1,1] collect o
    if istrans.count0 then
    (
    select istrans
    unhide selection
    )
    else messagebox"检查完毕."

    )
    on invselection pressed do
    (

    if selection.count0 then
    (
    unhide objects
    hide selection
    clearselection()

    )
    else messagebox"No selection"
    )
    on btn10 pressed do
    (
    for i in objects do i.name = " "
    for i in objects where (classof i == Editable_Poly or classof i == Editable_mesh) do i.name = uniquename "Polygon"
    for i in objects where (i.modifiers.count == 0 and classof i == box) do i.name = uniquename "Box"
    for i in objects where (i.modifiers.count == 0 and classof i == Sphere) do i.name = uniquename "Sphere"
    messagebox"rename done"
    )
    on btn21 pressed do
    (
    createdialog instance_check
    )
    on modifiers_on pressed do
    for i in selection where i.modifiers.count  0 do for m in i.modifiers.count to 1 by -1 do i.modifiers[m].enabledInViews = true
    on delmod pressed do
    (
    if selection.count  0 then
    for i in selection where i.modifiers.count  0 do for o in i.modifiers.count to 1 by -1 do deletemodifier i o
    else messagebox"至少选择一个物体"
    )
    on saveobj pressed do
    (
    if maxfilepath == "" then messagebox"请先保存当前MAX文件"
    else
    (
    selectionarray = (selection as array)
    if selection.count == 0 then messagebox"请先选择需要保存/导出的物体"
    else(
    file_path = getsavepath caption:"保存/导出到..." initialDir:(maxfilepath)
    if file_path == undefined do
    (
    messagebox("文件将保存/导出至 "+maxfilepath)
    file_path = maxfilepath
    )
    createdialog file_op
    )

    )
    )
    on import_but pressed do
    (
    createdialog imp_open
    )
    on set_pivot pressed do
    (
    if $ != undefined then $.children.pivot = $.pivot
    else messagebox"请选择一个顶端节点"
    )
    on WP_edit pressed do
    (
    clearselection()
    workingpivot.editmode = not workingpivot.editmode
    if workingpivot.editmode == false then WP_edit.caption = "Edit"
    else WP_edit.caption = "Editing"
    )
    on WP_use pressed do
    (
    clearselection()
    workingpivot.usemode = not workingpivot.usemode
    if workingpivot.usemode == false then WP_use.caption = "Use"
    else WP_use.caption = "Using"
    )
    on modifiers_off pressed do
    for i in selection where i.modifiers.count  0 do for m in i.modifiers.count to 1 by -1 do i.modifiers[m].enabledInViews = false
    )
    createdialog Mytools

    楼主 2015-07-04 09:41 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知