get 和set语句原理很简单,但非常好用,因为可以直接联系到RealFlow的用户界面。这两个命令完全共享同样的名称,你可以在节点(Nodes)和节点参数(Node Param)窗口看到。主要区别是get和set命令需要的参数(number)和数据类型参数不同。这命令不仅可用于遍历粒子,它们可以用在任何地方。
在这个例子里,Cone(圆锥体)已经添加到场景。参数列表包含了所有你需要使用的对像参数。最有趣的参数都在Node 标签下。在这你能找到最基本属性,像位移(position),Rotation(旋转)或Scale(缩放).在线帮助文档介绍的相应的get参数如下:
any getParameter( any )
告诉我们getParameter命令可以使用任何对像或任何数据类型。操作不限于参数,发射器,或摄像机。数据类型也可以是Integer,Float,Vector等。
你的数据类型可以使用getParameter命令,从Node标签下读出。当你看到三元值时,一定就是矢量:
Position 0.0 0.0 0.0
Rotation 0.0 0.0 0.0
Scale 1.0 1.0 1.0
Pivot 0.0 0.0 0.0
请注意:单个的矢量值(分量)是Float类型。甚至颜色也是用三个值,红,绿,蓝(RGB).Simulation和Dynamice数据类型是String(字符型).字段可以包含字句或表达式:
Simulation Active
Dynamics No
如果WetDry贴图设置为Yes,你可Integer值,像
@ resolution 256
@filter强度和@ageing值也是Float类型。
如前面所说,你要知道,get命令会输出什么数据类型,因为是setParameter的逆过程。你用确切的数据类型去改变合适的值。让我们看一个例子:
cone = scene.getObject("Cone01")
pos_global = cone.getParameter("Position")
结果是一个矢量,由三个Float组成。当计算完成后,你可以建立一个新的矢量。新的向量必须也要有三个Float(integers也是可以的)。你不能用String去替换。不然会产生语法错误:
pos_new = Vector.new("left", "up", "right")
下一个例子是一个完整的脚本。在RealFlow里准备一下,脚本作用是给圆锥y轴每帧位移增加0.2:
Events Script: ChangeConeYPos.rfsdef onSimulationFrame(): cone = scene.getObject("Cone01") # 1. Get global position data in Vector format pos_g = cone.getParameter("Position") # 2. Get components from the position Vector pos_x = pos_g.getX() pos_y = pos_g.getY() pos_z = pos_g.getZ() # 3. Add 0.2 to the y component new_pos_y = pos_y + 0.2 # 4. Build a new Vector new_pos_g = Vector.new(pos_x, new_pos_y, pos_z) # 5. Use the new Vector for position change cone.setParameter("Position", new_pos_g)
这个脚本与第三节的事件脚本非常相似。那个脚本增加了y和z方向 所有粒子位移。这里,我们只是针对单个对像。get语句过程的,分离和组合是和向量一样的。主要不同是最后一个语句:
cone.setParameter("Position", new_pos_g)
对于粒子,是这样:
particle.setPosition(new_pos_g)
注意粒子与别的对像是使用不一样的set和get命令。对emitter或mesh,是可以直接在对应Node参数窗口看到值的。Position或Velocity值不是都显示出来的。他们在内部使用。为了更快的访问速度和更好的区别,粒子属性不使用Parameter关键字。
还有另外一个不同点:getParameter命令只能取得一个参数,名称是“position".setParameter显示了”position"和new_pos_g.
因此用setParameter你必须要告诉RealFlow你想用哪种类型的数据改变(Position,pivot,roughness),然后新的值要用正确的数据类型。
在模拟时,可以在节点参数窗口监视更改的值。只是试一试y分量的position值。
圆锥在Y方向有一个恒定运动。
小提示: 不要从直接从本文章复制脚本到RealFlow。不一样的字体,字符设置和空格,都将导致错误。手动输入脚本是最好的,还能思考脚本到底是如何工作的。
用getParameter和setParameter能获得很多乐趣,因为你能更改,改变,打开关闭几乎所有东西。一些任务可以手动方便的解决,但脚本更精确一点。特别是碰撞,有时不能轻松的得到完全相同的碰撞。在两个模型,或粒子之间。使用Python脚本,解决起来只要短短几行代码。这是初始情况:
我们目的是让物体落下,碰撞到地板。所有物体都处于不同的位置。手动停止他们,可能很难。这个场景仅有三个模型,但假如有 20,30,或60个模型呢。根据你现在为止看到的方法,我们一直调用单个对像,如果有更多的对像时,就变成一个麻烦的事。为了使这个任务轻松,Realflow 有强大的对像选择工具。操作是,我将要用这个命令,名称是:
getSelectedNodes()
使用这个命令,你可以在节点窗口里选择到你想起作用的对像。
RealFlow分辨出你选中的,再把所有对像存储到List对像中。正确的表达式是:
items = scene.getSelectedNodes()
相像一下:选中三个对像,圆锥体(Cone),方盒(Cube),圆柱体(Cylinder),内部元素就会是:
items = [Cone,Cube,Cylinder]
下一步就是搜集所有正在碰撞到地面的对像项目。RealFlow也有能达到这个目的的函数。用这个命令要再创建一个List数据类型,因为有不只一个对像碰撞到地面:
floor = scene.getObject("Floor")
colliding_objects = floor.getCollidingObjects()
现在,我们要通过列表浏览碰撞对像并适当停用掉原始物体
if (colliding_objects != [ ]):
for object in colliding_objects:
object.setParameter("Simulation","Inactive")
用if条件语句检查,List colliding_objects 是否空的。表达式是
if (colliding_objects != [ ]):
意思是:如果 列表 colliding_objects 不等于空的,不执行下下面。空的列表写作[ ].你一种方法是检查列表长度(len)。
如果碰撞物体检测到就把存储到colliding_objects.并把Simulation参数设置为Inactive(不活动)。换句话说:当物体一完全碰撞到地面,就会被设置为不活动,并释放封闭的流体。下一页你将看到这个脚本的列表。
第一步分是初使化选中的项目并设置为活动。这在初使有多个模拟传递的情况下很有用,因为你不用每次模拟这个场景都要切换到之前值(初使值)。
程序能识别所有与地面进行碰撞的物体,并把它们存储到List变量中:
colliding_objects = floor.getCollidingObjects()
最后的if语句只是做很小的(建设)检查,Simulation状态是否改变了。所以如果Simulation状态设置成Inactive,脚本什么也不做。
碰撞后溶解(散开)
唯一的不足是,物体要与地面进行完全碰撞(后才能散开),之前他们都是失活(inactivate)状态。
第一次接触后就保持活动状态。一个繁琐的方法是利用模型的面或点进行检查。你可以把碰撞的面加入到一个列表。如果列表的长度大于0,物体就变为活动。
然后检查每个步骤或帧的对像状态是否活动,优化脚本。