自由者CG
标题: MaxScript概述 [打印本页]
作者: Freeman 时间: 2015-9-23 08:54
标题: MaxScript概述
MaxScript是3dsmax和AutodeskVIZ内置的脚本语言,它的形式非常自由和简单,它比较浅层,也几乎不涉及内存与数据的操作
MaxScript有很多结构是非常有特色的。如坐标系关联、原始物体和材质结构;可自动设置关键帧的动画模式;还可以使用表示3dasmax层级关系的路径名来访问场景物体。
MaxScript的语法非常简单,标点符号和书写规则都非常少。通过与命令行侦听器窗口交互,把工具安装为按钮,提取操作记录为脚本命令,可以大大的提高工作效率;
MaxScript可以足够充分的能力完成复杂的程序任务,因为它拥有矢量、矩阵、四元数等数据类型进行代数运算。MaxScript非常适合大数量对象的工作。例如编写复杂的选择程序,构建星空
MaxScript与3ds Max界面的整合性非常好。可以把脚本打包进工具面板的卷帘窗或非模块化的窗口里,或者与工具条的按钮、菜单、四元菜单或快捷键相关联。MaxScript还可以扩展或替换物体、修改器、材质、贴图、渲染或大气效果的用户界面。还可以创建自定义的网格物体、修改器和渲染特效用户界面。这种良好的整合可以使技术部门针对特定任务用脚本编写工具,使艺术家或动画师可以象在原有的3dsmax用户界面中那样通过点击式操作使用脚本工具
MaxScript支持格式化文本和二进制数据的输入和输出。所以,可以直接从3dsmax场景文件中直接输出文档的结构报告,或者从其他程序管理软件中读取包含场景布局、名称、贴图细节等内容的文件。外部文件和目录访问功能使MaxScript十分适合执行数据收集和分析、形成数据结构和渲染文件等的报告,通过内置的命令行和壳的支持与其他程序或脚本语言进行交互访问
。
MAXScript还可以被用作高层场景的输出工具。通过输出包含物体生成命令的脚本,使输出对任何高层3dsmax结构的应用成为可能。MaxScript甚至可以用来把max高版本文件转换到低版本的max中去,而不必求诸第三方数据格式
入门部分
一 认识Maxscript界面
打开脚本编辑器
打开脚本侦听器
Mini脚本侦听器
在侦听器中查看操作记录
在操作记录中提取脚本
编辑器中运行脚本
数字键盘回车单行运行或运行被选择语句
Ctrl+e 执行整个脚本
二入门实例
书写规则
书写形式非常自由,对大小写不敏感,一个表达式结束后进行换行时不需要加分号
2+5
4*6-7-9
a+b与A+B是一样的
换行,并可以在任何操作符后面打断语句换行,MaxScript会读取代码直到读取一个完整的表达式
a+b*c /d - e + f * g / h
a+b * c / d - e +
f * g / h
错误的换行
a + b * c / d - e +f
* g / h
用斜杠换行
a + b * c / d – e\
+f * g / h
如果在同一行中书写多个表达式,用分号分开
1+2;2^3;sin 30
注释,使用双减号
如
Sphere()--创建一个球体
变量赋值
变量赋值的语法
变量名=变量值
注意变量的名的书写由下划线或英文字母开头,可以包含任意数量的英文字母或数字
变量值可以是一个数,字符串或表达式
给变量赋予一个字符串
mystring = "This ismy string."
通过输入变量引用变量的值
Mystring
为这个变量重新赋值
mystring = "This isnot your string."
Mystring
基本的运算
35.0*2
Pi
Pi系统预定义的全局变量
4/3*pi*2.5^3
字符串操作
a=”MaxScript ”
b=”is a freeform language”
a+b
随机数的生成
Random 1 100
Random[0,0,0][100,100,100]
自运算
X=5
X=x+1
可以写作x+=1
加减乘除都可以使用这种快捷方式
X*=2
x-=2
x/=2
对物体进行操作
Box()
b=box()
b=box length:20 width:20height:20
对指定的物体进行操作
$box01
Select $box01
改变物体颜色
b.wirecolor=green
b.wirecolor=color 0 0255
b.pos=[0,0,15]
b.scale=[1,1,2]
move b [0,0,-15]
scale b [1,1.5,1]
rotate b 30 z_axis
rotate b -30 [0,0,1]
修改物体特有的属性
b.height=30
b.width=10
b.length=10
查看物体属性的两种办法
Showclass()
使用方法 Showclass “box.*”
可以在脚本侦听器窗口中显示 box类的属性
Box : GeometryClass {10,0}
.height : float
.length : float
.lengthsegs : integer
.width : float
.widthsegs : integer
.mapcoords : boolean
.heightsegs : integer
ShowProperties()
使用方法 showProperties b
需要针对专门物体
复制物体
Copyb
复制时可以修改一些通用属性,如位置,旋转,线框颜色
Copyb pos:(b.pos+[0,10,0]) wirecolor:green
使用循环语句进行阵列
P=b.pos
Fori=1 to 50 do
(
P.x+=50
Copy b pos:p
)
--------------------------------
For i=1 to 50 do
(
P.x+=50
C=Copyb pos:p
c.height=50+25*sin(i*360/8.0)
)
---------------------------
animateon
Fori=1 to 50 do
(
P.x+=50
at time i
(C=Copyb pos:p
c.height=50+25*sin(i*360/8.0)
)
)
创建星空
在+400和-400的空间中创建
用 showclass()查看球类的属性
Fori=1 to 500 do
(
P=random [-400,-400,-400] [400,400,400]
Sphere radius:(random 10 1.0) segs:4 pos:p
)
定义函数
FnstarField size segs num:100 =
(
For i=1 to num do
(
P=random (size*[-1,-1,-1]) (size*[1,1,1])
Sphereradius:(random 10 1.0) segs:segs pos:p
)
)
函数调用
Starfield500 4 num:300
MaxScript的基本结构——表达式
什么是表达式?在各种计算机语言的相关书籍中都有对其概念的介绍,尽管措辞不同,但都有一个共识,那就是——表达式是可以对其求值的任何语句。
在MAXScript中的任何结构都是表达式,都产生值,这种基于表达式的结构使MAXScript的书写非常简单,自由,而且十分直观。只要是可以书写<表达式>的地方,就可以书写MAXScript的任何结构。
我们用if结构来说明。
例如:
if a> b then print c else print d
我们可以把这个if表达式写进赋值语句中:
x = ifa > b then c else d
而if结构和赋值语句本身也是表达式,所以又可以把它们嵌套在一个if结构中:
x = if(if a > b then c else d) < e then f else (g = 23)
还有一个例子是块表达式。块表达式就是用圆括号括起来的一连串表达式,在语法描述中被标记为<块表达式>。
(
printa
printb
if a> b then print "the big a"
)
块中的表达式用换行分割,你还可以把这些表达式写到一行里,用分号(“;”)隔开:
printa; print b; if a > b then print "the big a")
块表达式本身也是表达式。它按顺序执行执行每一个子表达式,然后把最后一个表达式的值作为块表达式的值,一定要记住这一点。
Number
String
BooleanClass
Point3
Matrix3
Quat
Array
1. Number
MAXScript有两种数的类型:单精度浮点数和32位整型数。
这两种数的类型相当于max中使用的浮点数和整数类型。
123
123.45
-0.00345
1.0e-6
0x0E
.1
abs<数> 求绝对值,返回类型与给定的参数一致
mod<数1> <数>。模运算,即第一个数被第二个数除后的余数,返回结果为浮点数
ceil<数> ceiling是上限的意思,返回大于或等于给定数的那个最近的整数,返回类型总是为浮点数,如ceil 15.1的结果为16
floor<数> 求小于或等于给定数的那个最近的整数,返回类型总为浮点数.如floor 1.5的结果为15
三角函数
MAXScript中还有标准三角函数,角度以度为单位,返回结果为浮点数。这些三角函数是:
acos<数> --反余弦函数
asin<数> --反正弦函数
atan<数> --反正切函数
atan2<数> <数>--反正切函数的另一种形式
cos<数> --余弦函数
cosh<数> --双曲余弦函数
sin<数> --正弦函数
sinh<数> --双曲正弦函数
tan<数> --正切函数
tanh<数> --双曲正切函数
exp <数> -- e的指数函数
log<数> -- 以e为底的自然对数
log10<数> --以10为底的常用对数
pow<数> <数> --指数函数
sqrt<数> --平方根函数
随机函数
random<数> <数> --随机函数,返回值的类型为第一个参数的类型
seed<数>--随机种子函数
角度转换函数
degToRad<数>
把度转换为弧度,结果总为浮点数
radToDeg<数>
把弧度转换为度,结果总为浮点数
2. String
字符串是用括号括起来的一系列字符
如:
s1= "Truth, Justice And The American Way"
s2= "The American Way"
s3= "All That Stuff"
用.count属性访问字符个数
访问某个字符用索引数(下标)
如 s1[3]
3. BooleanClass
字面常量
true
false
on–-相当于true
off-- 相当于false
"true"as booleanClass
"false"as booleanClass
"on"as booleanClass
"off"as booleanClass
运算符
not<布尔值>
如果布尔值为false返回true,为true则返回false
<布尔值> and <布尔值>
如果两个布尔值都为true则返回true,否则为false
<布尔值> or <布尔值>
如果只有其中一个为true就可返回true。
And和or运算是非严格的。就是说,第一个布尔值就有可能决定整个运算的结果。
在一个and表达式里,如果第一个操作数如果为false,则结果必定为false,因此,第二个操作数就不再被执行
在一个or表达式里,如果第一个操作数为true,则结果必定为true,因此,第二个操作数就不再被执行
这种非严格的运算特性节省了运行时间,例如你想计算sin a,但是变量a的值有可能为undefined,
Point3和Point2
坐标是描述空间位置的数据类型,在MXS程序中被大量运用,如物体坐标、点的坐标、位图像素的坐标等等。二维坐标和三维坐标的书写方法:
[320,240] -- 二维点
[10,20, 30] -- 三维点
a=10
b=45
[10,20, 30]
[sina, 2 * b, a^2 + b^2] -- 包含表达式的坐标
讲述下
Normalize()
Dot
cross
Matrix3
这个变换矩阵是一个3D齐次矩阵,主要用于处理物体的坐标系统和变换信息。其实它的原型是4 x4矩阵
构造语法:
matrix3<row1_point3> <row2_point3> <row3_point3> <row4_point3>
matrix3[1,0,0], [0,1,0], [0,0,1], [0,0,0]
matrix3[0,-0.707107,0.707107] [1.41421,0,0] [0,1,1] [0,0,0]
Quat(四元数)
四元数常用于存储3ds Max物体的旋转信息。一个四元数由四个分量组成,一个实数标量部分,指定旋转的角度,另外三个指定一个虚拟的矢量,用来定义旋转轴。
MAXScript中的旋转是遵循右手定则的,显然角度为正数的旋转是逆时针的,与3ds Max UI中的习惯是一致的
构造器:
quat<x_float> <y_float> <z_float> <w_float>
x、y、z组成矢量部分,w是围绕矢量旋转的角度
quat<浮点数角度> <point3旋转轴>
Time
时间是MAXScript用来处理动画时间的。时间的解析单位为tick,解析度为每秒4800个tick,每帧160ticks。你可以使用ticks,帧,h.m.s或者标准化时间工作。
你可以混合数和时间进行运算。运算时,数总是被解释为帧数,如果为浮点数,则对应的帧为小数帧。
数在MAXScript内部总是被转换为tick为单位的时间再进行计算。
你可以数和时间值进行数学或比较运算,用as运算符进行时间和数之间的类型转换。
字面常量示例:
2.5s --2.5 秒
1m15s --1分15秒
2m30s5f2t--2分30秒5帧2ticks
125f--125帧
18.25f --18.25帧
1f20t--1frame20ticks
2:10.0 --2分10秒0帧 (SMPTE)
0:0.29-- 29帧(SMPTE)
0.45n -- 标准化时间
Array
组是一个经过排序的值的集合,组中的任何一个元素都可以是任何数据类型。你可以直接在程序中书写组常量,或者用MXS提供的组函数建立一个组。组常量有两种表达方式:
#(<expr> { , <expr> } )
#()-- 空组
例如:
#(1,2, 3)
#()
#(1,"foo",#(1.2,-4,#fred),[1,2,3]) – 注意组中包含一个嵌套的组
在组常量中包含表达式,如:
a=10
x=45
#(1,sin x, a * 2.3)
输出:
10.0
45
#(1,0.707107, 23.0)
控制程序流程
If 表达式
If表达式根据一个判断表达式的结果来确定是否执行一个表达式。
If表达式的语法有两种形式:
if<表达式> then <表达式> [else <表达式> ]
if<表达式> do <表达式>
ifa > b do (print d; print e)
a= (if d == 0 then 0 else a / d)
Case表达式的语法是:
case[ <表达式> ] of ( <条件> )
其中,<表达式>是一个测试表达式,<条件>是一系列被标记的表达式:
<因子>: <表达式>
default:<表达式>
例如:
new_obj= case copy_type.state of
(
2:copy $foo
3:instance $foo
default:reference $foo
)
For循环
for <变量名> ( in | = )<序列> ( do |collect ) <表达式>
其中<变量名>是访问<序列>时所使用变量的变量名,为了方便描述,我们把这个变量称为循环变量。循环变量从<序列>中依次取值。序列是一个值的集合。
fori = 1 to 10 do print i -- sequence numbers
foritem in table1 do x = x + item.height -- sequence an array
fort in 0f to 100f by 5f do sliderTime=t -- sequence time (given as frames, here)
bigones= for obj in $box* -- you can sequence pathnames!
whereobj.height > 100 collect obj
While和 Do循环
While和 Do循环都是用于重复执行一个表达式,直到判断表达式的结果为false终止。While和 Do循环是比较相似的。
语法为:
do <表达式> while <表达式>
while <表达式> do <表达式>
只要while <表达式>的结果为true,两种循环方式就一直重复执行do <表达式>。因为do形式的循环判断表达式在后,所以,至少会执行一次;而while形式的循环开始就要执行判断表达式,所以,有可能一次循环都不执行
界面编辑
界面的生成主要有三种办法
1. 用createDialog()生成窗口,必须有卷帘窗定义才可生成
2. 用newRolloutFloater()生成浮动窗体框架,然后添加卷帘窗
3. 用Utility()在工具面板中生成窗体框架,然后添加卷帘窗
窗口的主要构件为Rollout。
Rollout的语法:Rollout 变量名 标题字符串
在Rollout中添加局部变量,鼠标工具,函数定义
界面元素的常用属性
一个最简单的窗口生成
Rollout MyFirstUI "我的第一个窗口"
(
)
createDialogMyfirstUI height:200
加入界面元素
Rollout MyFirstUI "我的第一个窗口"
(
Button boxBt “Box”
Button sphereBt “Sphere”
)
createDialogMyfirstUI height:200
销毁窗口DestroyDialog()
加入界面元素
Try DestroyDialog MyFirstUI catch()
Rollout MyFirstUI "我的第一个窗口"
(
Button boxBt “Box”
Button sphereBt “Sphere”
)
createDialog MyfirstUI height:100
加入事件
On boxbt pressed do
box()
On sphereBt pressed do
Sphere ()
添加微调器修改物体属性
需要声明局部变量
Try DestroyDialog MyFirstUI catch()
Rollout MyFirstUI "我的第一个窗口"
(
Local b,s
Button boxBt “Box”
Button sphereBt “Sphere”
Spinner xposSpn “x_offset” range:[-999,999,0]
Spinner HSpn “BoxHeight” range:[-999,999,25]
On boxbt pressed do
Undo on
B=box height:hspn.value
On sphereBt pressed do
Undo on
S=Sphere pos:[xposspn.value,0,0]
On xposSpn changed val do
Ifs!=undefined do s.pos.x=val
On hspn changed val do
Ifb!=undefined do b.height=val
)
createDialog MyfirstUI height:100
让界面好看些
group "Create"
(
Button boxBt "Box" width:60across:2
Button sphereBt "Sphere" width:60
)
group "Parameters"
(
Spinner xposSpn "x_offset"range:[-999,999,0]
Spinner HSpn "BoxHeight"range:[-999,999,25]
)
其他常见界面元素
Label
Checkbox
Checkbutton
把生成星空的脚本生成界面
try destroyDialogStarfieldUI catch()
Fn starField size segs num:100 =
(
For i=1to num do
(
P=random (size*[-1,-1,-1]) (size*[1,1,1])
Sphere radius:(random 10 1.0) segs:segspos:p
)
)
Rollout StarFieldUI "StarField"
(
spinner szSpn "Space Size" range:[-100000,100000,400]
spinner numSpn "Number" range:[1,10000,500]
spinner segsSpn "Segs"range:[1,50,4]
button StarFldBt "Create StarFiled"
on StarFldbt pressed do
undo on
starfield szspn.value segsSpn.valuenum:numSpn.value
)
createDialog StarFieldUI
加入浮动窗口中:
nfloater=newRolloutFloater "Starfield" 200300
addRollout myfirstUInfloater
打包为宏脚本
MacroScript Starfiled category:”LearnMs”buttontext:”星空”
()
如果时间够用,简述下列应用
曲线生成
Spl=newSplineshape()
Addnewspline spl
Addknot()
编辑多边形
拉伸 移动点,获取表面法线
创建一个球体,分布一些box
欢迎光临 自由者CG (https://bbs.zhise168.com/) |
Powered by Discuz! X3.4 |