形状重组:基础知识

本部分更详细地说明了内联(重组)修改操作中形状重组的工作原理。

简而言之,形状重组可恢复细分形状之间的连通性,由此将独立的几何部分合并为一个单一的连续网格。

图示说明

合并已细分形状

许多建模目标需要将形状分割为多个部分,之后应在单个统一的形状上继续进行进一步操作。 例如,根据宗地面创建 F 形状建筑物覆盖区:

重组目的分割

使用 recompose 参数的内联关键字可以实现此功能。 可将细分形状重新组合为单个形状,并重建各部分之间的相邻关系,从而创建一个连续的网格:

  • 将合并共享折点(黄色)。
  • 在面边界上插入折点(红色)以在各部分之间创建共享边。

    重组添加折点

通过重组恢复连通性后,可以使用 cleanupGeometry 以移除共面之间的共享边,从而创建 F 形状面。 完整示例代码:

Init -->
    inline(recompose) split(x) { 10: X.
                               | ~1: split(z) { 10: X. | 10: NIL }* }
    cleanupGeometry(all,0)

连通性追踪

重新连接细分形状仅取决于拓扑关系。 当将 inlinerecompose 策略配合使用以派生形状时,CGA 会记住其连通性。 例如,上述规则将生成以下中间形状,其中 CGA 将追踪共享折点(黄色和绿色)以及沿共享边(橙色)插入的新折点(红色):

重组追踪

相邻关系的重建完全基于这些追踪的关系,而与空间中的折点位置无关。 例如,如果将下半部分向侧面平移,则上半部分也会随之平移:

已移动重组 F 形状

Init -->
    inline(recompose) split(x) { 10: t(0,0,8) X.
                               | ~1: split(z) { 10: X. | 10: NIL }* }
    cleanupGeometry(all,0)

有关折点位置的确定方式,请参阅折点合并部分。

几何修改

另一个重要的用例是修改(变换、分割、删除、标记、拉伸等)当前几何的某些部分。 例如,创建一个锥形体量或者移动屋顶的屋脊:

重组修改

将通过修改操作实现此功能:

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

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

modify 操作与 inline(recompose) 的工作原理相同。 实际上,要修改面组件,以下两行代码等效:

  • modify(f/m/g) { ... }
  • inline(recompose) comp(f/m/g) { ... | all= Keep. }

modify 操作会隐式地执行重组,并始终恢复完整几何。 主要区别:

  • inline(recompose) comp - 仅重组其生成的内容。 如果已创建边或折点形状(例如,使用 comp(e/fe)comp(v/fv))),则面会丢失。
  • modify - 重组已修改的部分,并重新添加未修改的几何,由此将对边和折点进行的编辑内容整合到原始面上。

在以下示例中,将对输入面的边进行修改以创建内嵌部分:

重组内嵌部分

首先将每条边分成 5 个部分,然后将中间部分向内移动。 然后,形状重组会自动重新连接已修改的边,并将其重新合并为原始面。

InsetExample -->
    modify(fe) { all: split(x) { ~1: X.| 1: X. | 3: t(0,0,-2) X. | 1: X. | ~1: X. } }

折点合并

形状重组通过合并共享折点(即源自同一源折点的细分形状中的折点)来重新连接形状。 将保留所有已应用的变换:将通过累加共享折点相对于原始折点位置的各自偏移来合并共享折点。

在以下示例中,将调整底部边和右侧边的比例。 将为共享的紫色折点添加两个偏移,由此将这两个偏移相加并应用于原始位置,以放置合并后的折点。 红色和黄色折点各自具有一个偏移,因此其最终位置与重组前的位置相匹配。

重组移动折点

Init -->
    modify(fe) { 0: s('0.5,0,0) center(x) X. 
               | 1: s('0.6,0,0) center(x) X. }

沿共享边合并

沿这些边插入的新折点将遵循应用于共享边的变换。

在以下示例中,可将形状分割为底部和顶部两部分。 将对底部进行缩放并将其细分为三等份,将顶部细分为六等份。 在重组过程中,将沿着变换后的边(红色、紫色)插值顶部部分的新折点。 将自动合并共享折点(黄色、绿色)以及在相同相对位置处分割边的折点(紫色)。

重组折点移动分割示例 1

Init   --> inline(recompose) split(x) { '0.5: Bottom | '0.5: Top }
Bottom --> s('1,'1,'1.5) center(z) split(z) { '1/3: X. }*
Top    --> split(z) { '1/6: X. }*

同样地,在本示例中,将调整底部的比例,并对顶部进行垂直分割。 新折点(红色)将遵循共享折点(绿色)的变换。

重组折点移动分割示例 2

Init   --> inline(recompose) split(x) { '0.5: Bottom | '0.5: Top }
Bottom --> s('1,'1,'1.5)
Top    --> split(x) { '0.2: X. }*

累积偏移

当单独变换相邻形状时,形状重组会将这些变换累积到共享的折点和边上。

在本示例中,四个面中的每个面将以作为单独的形状向上平移。 当进行重组时,将会累加共享折点的平移:中心折点将累积四个偏移(每个形状一个),中间边界折点将累积两个偏移,而拐角折点仅累积一个偏移。

FourFaces --> modify(f,noAlign) { all: t(0,1,0) X. }
累积偏移

注:
为了避免偏移累积,请直接对折点,而非面或边应用变换,或者使用多个连续的、不冲突的 modify 操作。

当前不受支持的操作

以下操作尚不支持连通性追踪(以及由此产生的形状重组):

仍然可以在 modifyinline(recompose) 内部使用这些操作,但是生成的形状不会自动与几何的其余部分重新连接;只是简单地将其附加在一起。

相关内容

示例

已平移平面

输入平面将分为三个相等的部分,将右侧部分向上移动。 形状重组将各个部分重新连接起来,由此创建一个倾斜的中间部分。

Init -->
    inline(recompose) SplitAndTranslate

SplitAndTranslate --> 
    split(x) { ~1: X. | ~1: X. | ~1: t(0,2,0) X. }
重组已平移平面

将首先对输入平面进行拉伸,然后按照相同的规则修改顶面。 形状重组可将已分割部分重新连接起来,并将已修改的顶面与侧面重新整合在一起。

请注意:将不再需要 inline(recompose),因为始终由 modify 操作隐式执行形状重组。

Init -->
    extrude(5)
    modify(f,noAlign) { top: SplitAndTranslate }

SplitAndTranslate --> 
    split(x) { ~1: X. | ~1: X. | ~1: t(0,2,0) X. }
重组已拉伸平面

在此变体中,将删除所有已分割部分(使用 NIL),但修改仍然应用于侧面。

Init -->
    extrude(5)
    modify(f,noAlign) { top: SplitAndTranslateNIL }

SplitAndTranslateNIL --> 
    split(x) { ~1: NIL | ~1: NIL | ~1: t(0,2,0) NIL }
已删除分割部分的重组变体

随机分割和变换

在本示例中,将随机分割输入面,并按随机量对每个单元格进行平移。 形状重组将所有部分重新连接起来,由此形成一个连续表面。

Init -->
    inline(recompose) RandomSplitX

RandomSplitX --> split(x) { rand(0.5,1): RandomSplitZ | ~1: RandomSplitX }
RandomSplitZ --> split(z) { rand(0.5,1): Cell | ~1: RandomSplitZ }
Cell         --> t(0, rand(-0.2,0.2), 0)
随机分割和变换