modify 操作

语法

  • modify(component) { selector operator operations | ... }
  • modify(component, scopeAlignment) { selector operator operations | ... }

参数

  1. component, scopeAlignment, selector, operator, operations
    这些参数与 comp 操作的相同。

描述

modify 操作用于编辑当前几何的所选部分。 与 comp 操作类似,该操作将形状划分为拓扑组件(由 component, selector, operator 定义),从而生成新形状,可根据指定 operations 对新形状进行修改。

comp 操作不同,modify 操​​作始终隐式执行形状重组(请参阅形状重组),即重新组合已编辑组件和剩余几何。 对于面组件,以下两行代码等效:

  • modify(f) { ... }
  • inline(recompose) comp(f) { ... | all: X. }

内联 comp 操作相比,modify 将自动恢复未修改的几何,由此无需使用“| all: X.”子句。 该操作还支持在操作后恢复为完整几何的同时修改边和折点组件。

注:

modify 操作仅更改当前形状的几何,而不会向形状树中添加后续形状。

comp 形状属性

每个生成的形状都设置了许多 comp 形状属性。 有关详细信息,请参阅 comp 属性

相关内容

示例

修改后的屋脊

Init -->
    extrude(5)
    comp(f) { top: ModifiedRoof | side: Facade. }

ModifiedRoof --> 
    roofHip(45)
    modify(e) { ridge: t(0,2,0) X. }

屋脊向侧面移动 2 米。

修改屋脊

锥形体量

Init -->
    extrude(5)
    modify(f) { top: s('0.5, '0.5, '0.5) X. }

将调整已拉伸体量顶部的比例以创建倾斜立面。

修改立方体

波纹立面

const OpeningL = 2
const Depth = 0.75
const InnerL = 1	

Init -->
    inline(recompose) split(x) { 5:  tag("Front") F. 
                               | ~1: tag("House") H. }
    modify(e) { isTagged("Front") && isTagged("House"): 
        split(x) { ~4: CreateOutset }* }

CreateOutset -->
    split(x) { ~1      : Wall. 
             | 0.01    : tag("Side") Side.
             | OpeningL: tag("Outset") Outset
             | 0.01    : tag("Side") Side.
             | ~1      : Wall. }

Outset --> t(0,-Depth,0) s(InnerL,0,0) center(x)

首先将输入形状划分为房屋和前部覆盖区并进行标记,然后使用 inline(recompose) 对其进行重新组合。 然后修改连接边,并将其分割为重复的外扩部分。 将通过细分边、标记参考部分以及变换中心线段来构建每个外扩部分。 形状重组会自动将已修改边与覆盖区合并,从而生成波纹图案。

之前修改外扩部分
Init -->
    ...
    comp(f) { isTagged("House"): BuildHouse }

BuildHouse -->
    extrude(3)
    cleanupGeometry(all,0)
    comp(f) { isTagged("Side")  : Blue
            | isTagged("Outset"): Green
            | all               = White. }

Blue -->   color("#0399F5")
Green -->  color("#09DE1F")

extrude 操作会自动将之前已应用的边标签传播到相应立面。 这些标签用于为建筑立面着色。 cleanupGeometry 操作用于合并相邻的共面墙多边形。

之后修改外扩部分

双曲格网

attr Max_Height = scope.sx/2

Paraboloid with(
    center := getPivotCoord(scope.sx/2, 0, scope.sz/2) 
    cenX   := center[0]
    cenZ   := center[2]
    a      := getDampingFac(scope.sx/2)
    b      := getDampingFac(scope.sz/2)
    yPos   := scope.ty
)-->
    inline(recompose) Grid
    modify(v, noAlign) { all: Move(cenX, cenZ, a, b) }
    set(scope.ty, yPos)

Grid -->
    split(x,noAdjust) { '0.1: split(z) { '0.1: Cell. }* }*
		
Move(centerX, centerZ, a, b) with(
    x := scope.tx - centerX
    z := scope.tz - centerZ
)-->
    t(0,hyperbolic(x,z,a,b),0)

hyperbolic(x,z,a,b) = (z*z)/(b*b) - (x*x)/(a*a)

getPivotCoord(x,y,z) = convert(scope,pivot,pos,[x,y,z])
getDampingFac(l) = l / sqrt(Max_Height*0.5)

该示例首先使用 inline(recompose) 将输入形状分割为 10x10 格网。然后,移动每个折点以创建双曲面。 最后,将 scope.ty 恢复为其原始值,以确保新形状完全位于输入形状上方。

该规则将使用 Max_Height 属性来控制双曲面的高度(防止二次函数针对大型输入形状而产生过大数值)。

noAlign 参数可确保所有折点范围共享相同坐标系。 将保留原始枢轴,因此每个折点的范围都相对于该参考点,由此可以直接从范围转换中读取其位置。

修改抛物面

双曲屋顶

attr Max_Height = scope.sx/2
Init --> 
    extrude(5)
    modify(f,noAlign) { top: Paraboloid }

Paraboloid 规则可直接用于修改已拉伸体量的顶部。

修改抛物面屋顶

Chaikin 角点切割算法

修改平滑步骤
Init -->
    ChaikinSmoothing(3)
	
ChaikinSmoothing(n) -->
    case n > 0:
        modify(fe) { all: SplitEdge }
        modify(fe) { isTagged("Collapse"): s(0,0,0) X. }
        cleanupGeometry(vertices,0)
        ChaikinSmoothing(n-1)
    else:
        Done.

SplitEdge --> 
    split(x) { '0.25: CornerCut. 
             | ~1: Fixed. 
             | '0.25: tag("Collapse") Collapse. }

本示例将实现 Chaikin 角点切割算法以平滑面边界。 每次迭代都将每条边分割为三部分,并折叠最后一部分。 通过折叠每条边的末端,同时折叠下一条边的起始端,由此逐渐切割角点并产生均匀的平滑效果。

cleanupGeometry 操作将合并折叠边的折点。

修改平滑示例