cityengine瞎玩1: 简易围栏
介绍一段简单的cituengine程序建模代码
(1)
稍微说一下我对cityengine程序建模的理解
daz3d是个“整合”软件,cityengine也是个整合软件,但坑爹的是这软件功能太少,10年都没啥变化,并没有发展成一个“能让设计师搭积木般展现想象力”的软件,一切行为都需要你理解代码原理,否则你连个cube也做不出来
ce的本质是“替换”,ce里有2个基础物体,作为房屋地基的“多边形线”和作为道路的“线段”。两者各自拥有一些属性,两者又都可以生成“平面”,平面上又生成立方体,立方体分解成墙壁,墙壁上又生成突出部,以此类推
(2)
今天做一个“简易围栏”,使用ce版本为2015.1
先看看效果,如下图,

怎么做呢?
事先准备好一个围栏模块,如下图,一百多个面

下面是代码:
总共有四段
const wide_WeiLan1=0.5
const long_WeiLan1=3
const high_WeiLan1=4
const mod_WeiLan1=
fileRandom("WeiLan1/*.obj")
const long_corner=1
Lot-->
offset(-wide_WeiLan1)
comp(f){inside:NIL |
border:ground_WeiLan1}
ground_WeiLan1-->
split(x){
long_corner:ground_unitWeiLan1 |
{~long_WeiLan1:ground_unitWeiLan1}* |
long_corner:ground_unitWeiLan1}
ground_unitWeiLan1-->
case !(split.index==0||split.index==split.total-1):
rotateScope(90,0,0)
s('1,high_WeiLan1,'1)
i(mod_WeiLan1)
else :extrude(high_WeiLan1)
(3)
怎么样,很简单的代码吧hh
下面稍微解释一下代码
[1]
第一段代码
写规则之前的准备,也就是定义
const wide_WeiLan1=0.5
定义常量
const mod_WeiLan1 = fileRandom("WeiLan1/*.obj")
随机导入模型,其实有多种导入模型的方法,不过这种比较简单粗暴
这里根目录是,你的ce文档里,你的project名字文件夹里,assets文件夹
在其中建一个WeiLan1文件夹,然后把之前做的围栏模块放进去就行了
[2]
第二段,
"Lot-->"
ce代码的写法就是这样: a-->b b-->c c-->d 一步步替换下去
所有代码从Lot开始,Lot就指代你赋予代码的那一片平面,那么为什么要写“Lot”呢?写成别的不行吗?
有的教程说这是“约定俗成的”,实在是知其然不知其所以然,让人摸不着头脑

如上图,当你选中一块“地基”时,inspector窗口会显示一些信息,你会注意到里面有个StartRule,这里的“Lot”是官方设定初始模块名。如果你点选一段“道路”的中间部分,StartRule就是“Street”
也就是说,如果你给“地基”赋予规则,系统会识别你代码里的“Lot”为初始模块,如果你给“道路”的中间部分赋予规则,系统会识别你代码里的“Street”为初始模块
那么写成别的会怎么样?比如“lot(小写),street,ground”。其实问题也不大,系统会把你的第一个模块识别成初始模块
但是,如果你想把整个城市写成一个复杂规则,比如说“地上建房,路上建灯”,那么系统需要识别多个不同的初始模块,这时区分Lot和Street就很必要了
所以如果是地基的规则,还是推荐你把第一个模块名写成Lot
[3]
offset(-wide_WeiLan1)
地面向外延伸一圈,负数则为向内延伸
comp(f){inside:NIL |border:ground_WeiLan1}
a. comp()是分离函数,括号里针对不同对象,一般都是f,即face的缩写
b. 大括号里,冒号前的单词是规定的,如果前面用了offset函数,comp函数里就要用inside,border,意思是分成内部,外框两部分
c. 大括号内多个部分用“|”隔开
d. 冒号后的单词是自己写的,意思是下一个规则的名字为“ground_WeiLan1”
e. NIL在ce代码中指代空集
[4]
第三段,其实只有一行
ground_WeiLan1-->split(x){ long_corner : ground_unitWeiLan1 | {~long_WeiLan1 : ground_unitWeiLan1 }* | long_corner : ground_unitWeiLan1}
a. split() 为切分函数,括号内x意思是沿x轴切分,
b. 冒号前为切分每段长度,
c. “~”为取近似值均等切分,
d. “*”为以该数值一直切分到结尾
[5]
第四段,
ground_unitWeiLan1-->
case !(split.index==0 || split.index==split.total-1) :
rotateScope(90,0,0)
s('1,high_WeiLan1,'1)
i(mod_WeiLan1)
else :
extrude(high_WeiLan1)
a. case是ce的条件函数
b. 用split函数得到的模块内置一个split.index属性,即切分编号
c. rotateScope函数,旋转范围框 (这个概念有点复杂,以后再说)
d. s函数,限制缩放,x轴z轴不变,y轴为4米
e. i函数,替换模型函数,把一个空的范围框替换成单段围栏obj模型
f. extrude函数,即挤出功能,把地面变成盒子
g. 本段代码的意思是,编号0和编号-1——即第一个和最后一个平面——挤出成盒子,除这两个地面外替换成围栏
(4)
如果你想做个非常精致的围栏自然也是可以的
当然,我觉得这个软件的意义还是在于画一个草稿,可以极大地减少前期成本
但是再怎么减少,前期也不能变成后期,后面的工作还是交给maya,blen之类的吧
仅供参考
毕竟还是软件瞎玩系列hh
















































































