3D脚本 maxscript入门教程(3)

3D脚本 maxscript入门教程(3)

 (2013-05-23 18:24:57)
标签: 

3dmax

 

maxscript

 

建模

 

it

分类: 脚本
三、创建和操作具有复杂关系的对象
常量;
变量,变量和属性的关系;
运算符和表达式;表达式:求值的规则,输入的每一行代码都是表达式,因为它总是返回一个值。
对象引用:有的书叫双词模式(引用另外一个对象的属性值作为自己的值。);
数组和集合等:数组(一个系列的数据组合),数组和变量的关系;
流程控制:选择和循环,条件选择。

闻着春天里散发出来的花香味,忍不住去欣赏那些美丽的花朵,它们被一些长得井然有序的绿叶衬托着;穿过长着杂乱小草的林间小道,惊动了树上正在戏耍的鸟儿,它们飞向两旁看似有序又无序的青松翠竹林中,瞬间不见了踪影;走在马路上,两旁定有一排排梧桐或扬柳,如果你的眼力好的话,发现树的皮肤上有好多忙忙碌碌的蚂蚁;白天工作了一天,夜晚来到一个幽静的小河边,抬头望着满天繁星,低头看着水中的倒影,心情好多了,不禁思潮起伏。

不管是四时花草树木,八方飞鸟走兽,无论是静止着的、运动着的,哪怕是无序的事物,都存在有一定的内在关系。那么到底是怎么样一个内在关系呢?要有具体的内容啊!

最简单最常见的是对称关系,例如昆虫的翅膀,羊头上的角;还有直线关系,例如路边两边的树;最没规律的关系是那些运动着的和杂乱无章的事物,例如飞动着的鸟儿,忙碌着的蚂蚁,水中冒出的气泡,就把它们称为随机关系吧;既没有规律又很杂乱的关系是噪音关系,蝴蝶翩翩起舞的轨迹,杂乱的野草的分布状态;最美丽的关系是那些按一定的曲线而存在的事物,例如波澜起伏的水面,它是正弦波或者正弦波的叠加关系,小朋友向天空方向扔出的石块的运动轨迹,就是一条抛物线;还有起伏不平的崇山峻岭、狐狸摇动着的尾巴,曲折前进的蛇类等等无不存在着某种关系。

既然能找出这些事物的内在关系,能否用MAXScript来再现这种关系呢?答案就是一个字:能!

1、常量和变量

要实现复杂的程序,首先要掌握数据的表现方法,在脚本中用常量和变量来表现。现实生活中有些事物是相对固定的,有些则是经常变化的。就拿人来说吧,人的性别是不变的,年龄是每过一年就增加一岁;拿我们用的电脑硬盘来说,总容量是不变的,但可用磁盘空间经常是变化的。在MAXScript中,把那些不能改变的量称为常量(Literal Constants,字面常量,简称常量),可以变化的量称为变量(Variables)。

例如15,“Hello”等,从字面上一看就知道这些值是不能改变的,所以把常量又叫做字面常量,用age来年龄,而这个age是在变化的,所以age是变量。那么别人问李四的age是多少,去年问的时候李四也许回答是21岁,今年有人问李四,当然就是回答是22岁了。如果他回答age,那别人就不知道他的年龄了,他必须说出具体的数字出来。age是变量名,22岁是变量值。那么在MAXScript中该怎么表示?那就是给变量赋值,等于号是赋值符号,输入 age=22 ,脚本监听器中返回22,又如李四的银行存款 , 建行的是20000元,输入 money1=20000 , 工行的是36000,输入 money2=36000,请问用money表示李四这两个银行存款的总和,程序代码应该怎么写?没学过编程的人也许可能输入money=56000,呵呵,这个也没有什么错,不过输入money= money1+ money2,结果如何?一分钱也少不了,照样返回56000,程序自己完成了加法计算,减轻了我们大脑的负担。

变量就像一个容器,可以存储不同类型的数据。数目,字符串,数组,对象都可以存放在变量中。

现在就来详细解说变量。在程序运行期间,系统会在内存中为程序分配一块内存单元,用来存储各种不同类型的数据。而想访问这个内存单元,就要使用一个标识符来标识它,就像你到单位去找一个人一样,先要告诉这个人的名字。这个标识符就是变量名,内存单元中装载的数据就是变量值。程序可以通过变量名来读取数据。把数据放到内存中就是为变量赋值,=是赋值符号。我们把上面的写在一块,如下:
money1=20000
money2=36000
money= money1+ money2
当程序运行第一句代码时,分配一块内存,用money1作为这块内存的变量名,然后把2000装入这块内存中作为变量的值,第二句同上,运行到第三句时,分配一块内存,取名为money,程序取出money1和 money2中的数据让它们相加 ,把相加的结果56000装入名为money的内存单元中。

现在回忆一下以前是如何改变对象属性的。例如前面提到改变box01的长度,语法是 $Box01.length=20,这和给变量赋值的语法是一样的。从这里可以看出,对象的属性实质上也是一个变量,只因为是对象特有的变量,就称为属性了,访问变量直接用变量名,访问属性要在属性名前加上对象名,中间用一个小数点隔开,称为点语法,这就是变量和属性的关系。既然可以把一个变量分配给另外一个变量,就可以把一个对象的属性分配给一个变量,也可以把一个变量分配给一个对象的属性,还可以把一个对象的属性分配给另外一个对象的属性,有的人把它称为双词模式。有的人会想,现在到了这一步,索性来个一不做二不休,把整个对象分配给一个变量,以后访问时更加方便,这也是允许的。举例如下:
height=50
myBox=box length:20 20 height:height
zPos=mybox.height+10
mySphere=sphere radius:10 pos:[0,0,zPos]

结果如图3-1所示
图3-1

--第二句中height:height是把变量height分配给这个box的height属性,第三句是算出Z轴的坐标,准备分配给后面要产生的球体的Z轴坐标,第四句pos:[0,0,zPos] 是把变量zPos的值分配给球体的Z轴。

注:鉴于要有一定基础,变量的作用范围(即全局变量和局部变量)和增量放在第五部分了。

2、数组和集合

数组(array),是一系列有序数据的集合,每一个数据就是一个元素,它有两种表现形式:
#( 表达式 1 , 表达式2 …… )
#( ) --空数组

例如把常量15,16.2,80这几个数据放在一起,就可以用数组存放:
#(15,16.2,80)

把变量放到数组中:
x=10
y=20
z=30
#(x,y,z)--返回#(10, 20, 30)

把数组分配给一个变量 :
arr=#(x,y,z)--返回#(10, 20, 30)

访问数组元素:
arr[2]--第二个元素,返回20

改变数组元素的值:
arr[1]=236
arr--再次访问数组时,其内部元素的值已经改变了,返回#(236, 20, 30)

选择集(selectionSet)

这个对应于手工在场景中命名的选择集,也可以用脚本命名选择集。

先创建几个对象,输入:
b01=box pos:[-50,-50,0]
b02=box pos:[50,-50,0]
sp01=sphere pos:[0,0,0]
sp02=sphere pos:[50,50,0]
sp03=sphere pos:[50,50,0]
下面的代码创建一个名字为"盒子集"的选择集,它包含有刚才创建的两个box:
selectionSets["盒子集"]=$box*
下面的代码创建一个名字为"球体集"的选择集,它包含有刚才创建的两个sphere:
selectionSets["球体集"]=$sphere*
在工具栏中点击命名选择集按钮,可以看到刚才创建的选择集。

输入selectionSets["盒子集"][1],访问第一个元素,结果返回:
$Box:Box01 @ [-50.000000,-50.000000,0.000000]
输入move selectionSets["球体集"] [0,20,0],整个“球体集”向Y轴移动了20。

集合(collections)

在使用MAXScript 时有许多值都是一系列的集合,很明显的有数组、 通配符路径名选择集,内置对象集。集合不用你特意去指定,它是系统自动完成的。例如我们现在用下面的代码创建一些对象:
box()
box pos:[60,0,0]
box pos:[-60,0,0]
sphere pos:[0,70,0]
omnilight pos:[0,-100,150]
circle()

既然是自动完成的,那我们就直接访问了。访问场景中的对象可以使用路径名,前面讲过用路径名,访问单个对象用美元符号$加上对象的名字就可以了,但如果要把刚才创建的三个box一起向Y轴移动100,应该怎么办呢?使用带有通配符的路径名:
$box*.pos.y=100
$box* 表示场景中所有以box开头的对象,*表示任意个字符。

如果把那三个box和一个球体一起操作呢?它们都是内置几何体对象集:
select geometry --选择所有的几何 体
geometry.pos=[0,0,0]-把所有的几何体移动到时原点

选择所有的对象,下面提供有两种方式:
select $* --以路径名的方式选择所有的对象
select objects --以内置对象集的方式选择所有的对象

下面把内置对象集列出,以供参考:

对象集 (ObjectSet)

对象集是描述主场景对象种类的。

objects -- 全部对象

geometry -- 标准的 3ds Max 分类(categorie)

lights--灯光

cameras--摄像机

helpers--帮助物体

shapes--二维形状

systems--系统对象

spacewarps--空间扭曲

selection -- 当前选择的对象

集合的属性
接着上面的内容进行操作。
输入selectionSets["盒子集"].center 返回"盒子集"中心 [0,-50,12.5]
输入selectionSets["球体集"].count 返回"球体集"总数3
输入selectionSets["盒子集"].max 返回"盒子集"最大范围[62.5,-37.5,25]
输入selectionSets["盒子集"].min返回"盒子集"最小范围[-62.5,-62.5,0]

这四个属性适用于对象集(ObjectSet) ,路径名(PathName)、选择集(selectionSet)等集合

变量、数组和集合之间的关系

从数组、对象集、路径名、选择集等之间的定义可以知道,它们都是存放的数据,这些数据类型可以是数目,字符串,也可以是对象,这和变量是一样的用途,这么说来,它们的实质是变量的集合,因此把它们统称为集合(collections)。集合中的每一个元素都是一个变量,所以访问集合中的元素可以像访问数组中的元素一样来访问,对于数组中的每一个元素可以像对待变量一样。输入:
Box()
Sphere()
然后选择它们,再输入:
selection[1]
监听器窗口中会返回第一个元素的路径名和位置。

3、表达式

要得到想要的值,就要对数据进行计算,计算规则不同,其结果也就不一样。例如2和3两个数据,按减法规则来计算,结果是-1,按加法来计算,结果是5。像这种按某种计算规则来求值的公式,MAXScript把它称为表达式(expressions,简写为expr),表达式是一种求值的规则。从语法的角度来看,用操作符把操作对象连接起来的式子称为表达式,有的编程语言也叫语句 (statements) ,意思一样。我们以前在学校里学的加减乘除四则运算也可以看作是最简单的表达式了,也就是说我们没有编程之前就会使用表达式了。前面提到的常量,变量,数组 ,构造器,函数以及输入的任何一句代码,都是表达式,因为总会返回一个值。 MAXScript有大多数编程语言常见的表达式,例如数学表达式(Math Expressions),比较表达式(comparison expressions ),逻辑表达式(Logical expressions ),以及MAXScript特有的关联表达式(Context expressions ),后面的教程会涉及。下面是有效的表达式:
x=1
y=2*3+5
print y --输出y的值到屏幕上

上面的代码可以写成一块,这就是块表达式(block-expression):
(
x=1
y=2*3+5
print y
)

还可以把这三行代码写成一行,用分号;把它们分开:
( x=1; y=2*3+5; print y )

几个常用的表达式
比较表达式(Comparison Expressions)

比较表达式总是返回两个布尔值中的一个,true 和 flase ,true(真)表示条件成立,flase(假)表示条件不成立。这个表达式特别有用,很多情况下都会用到,常常和 if ……then ……结合使用。比较表达式在小学数学中就有了,就是那些大于,等于,小于号连接起来的式子,有一点要注意,那就是等于号要用两个=表示,一个是表示赋值符号。示例如下:
10= =10 --条件成立,返回 true
11= =10 --条件不能成立,返回 flase
11!= 10 --条件成立,返回 true
11>= 10 --条件成立,返回 true
11<= 10 --条件成立,返回 true

x=8
y=36
x>y--条件不能成立,返回 flase


逻辑表达式(Logical Expressions)

逻辑表达式有or、and 和 not 三种,同比较表达式一样返回一个布尔值 true 和 flase之一,它是对比较表达式的进一步组合计算,也就是说对true和flase的重新组合,得到一个新的布尔值。

or(或),只要两者有一个成立,那么整个都成立,例如在中国发现了外星人或者在美国发现了外星人,只要有谁发现了一个,那么就说明这个宇宙上还有另外的生命。示例:
x=8
y=36
x= =8 or y= =8 --有一个成立,返回 true

and(与),两者要同时成立,才能整个成立,否则都不能成立。真是有福同享,有难同当的患难之交啊,一损俱损,一荣俱荣,关系密切。从中也可以看出些人生道理出来,那就是两个人合伙做事一定要同心协力,任何一个怀有异心,就办不成事。示例:
x=8
y=36
x= =8 and y= =8 --有一个成立,另一个不成立,返回 flase
x= =8 and y= =36 --两者同时成立,返回 true

not(非),对立派,总是唱反调,你要上山,它就要下水,你说是对的,它偏要说是错的。示例:
a=13
a>10 -- 返回 true
not a>10 -- 因为a>10 是true,所以not a>10返回 flase
原文地址:https://www.cnblogs.com/superjn/p/6179412.html