inside / overlaps / touches 函数(遮挡查询)

语法

  • bool inside()
  • bool overlaps()
  • bool touches()
  • bool inside(target)
  • bool overlaps(target)
  • bool touches(target)
  • bool inside(target, label)
  • bool overlaps(target, label)
  • bool touches(target, label)

参数

  1. target - selector
    • intra - 针对同一形状树中的遮挡物形状(即来自同一初始形状)进行检查。
    • inter - 针对其他形状树中的遮挡物形状(即由邻域中的其他初始形状生成)进行检查。
    • all - 检查 intrainter

    如果未给定选择器,则将使用 all

  2. label - 字符串
    如果给定标注标识符,则将仅对与请求的 label 匹配的遮挡物形状执行遮挡查询。 空标注的行为与未标注的遮挡查询相同。

返回

如果当前形状几何完全位于另一个形状的封闭几何内或者与之重叠或接触,则返回 true,否则返回 false

描述

针对形状之间的相交的遮挡查询测试。 可使用四个不同的布尔函数检查当前形状几何的空间上下文:

  • 如果当前形状几何完全位于由 targetlabel 指定的一个封闭几何的内部表面上,则 inside() 会返回 true
  • 如果当前形状几何部分位于由 targetlabel 指定(反之亦然)的一个封闭几何的内部,则 overlaps() 会返回 true
  • 如果当前形状几何与由 targetlabel 指定的一个封闭几何重叠或具有平面接触,则 touches() 会返回 true

三个遮挡函数的可视化定义(采用白色:遮挡物形状;采用红色:查询形状):

遮挡函数的可视化定义
注:
  • 在任何情况下,仅针对形成闭合表面的几何执行测试(即,没有边界边的防水网格)。
  • 详细了解有关条件和内部遮挡中的遮挡查询的重要特性。

未标注遮挡查询

如果未给定 labellabel 为空,则将针对实际选择的封闭遮挡物几何(使用规则集自动生成)测试当前形状几何:

  • 叶形状
  • 已应用组件分割偏移的形状。 这些操作通常表示从体量到表面的转变。 此外,这些操作通常应用于简单的几何,以针对遮挡进行高效测试。
  • 任意标注遮挡物形状。

内部遮挡

内部遮挡查询仅针对不是查询形状的父项/祖先或子项/后代的几何执行,因为自上而下的语法建模方法导致这些几何最有可能遮挡当前形状。

相关内容

示例

内部遮挡

此示例演示了对形状树的形状执行的 touches 遮挡查询(内部遮挡)的结果。 由于未给定标注,遮挡查询将针对自动生成的遮挡物形状进行测试:应用了组件分割的封闭几何。 请注意,所有遮挡查询都不会考虑先前的遮挡物形状,即切片源自的组件分割体积。 不会考虑在组件分割和条件 false 实例中构造的叶形状,因为这些形状未形成封闭几何。

Init --> extrude(15)
         split(x) { ~5 : Step }*
		
Step --> s('1, '0.7 * (split.index + 1), '1)
         comp(f) { side: Facade | top: X. }
	
Facade --> split(y) { 4 : Tile }*	

Tile --> case touches(intra):
             color(1,0,0) X
          else:
             X.
内部遮挡

相互遮挡

在此示例中,House 规则应用于两个相邻初始形状(相互遮挡)。 将自动创建闭合遮挡物形状:块(组件分割)和屋顶(叶形状)。 不会考虑更多的叶形状,因为这些形状不会形成封闭表面。 inside 查询会阻止插入不可见的切片,因为这些切片被相邻块或屋顶遮挡。 touches 查询会阻止创建遮挡相邻块或屋顶的窗户,改为插入墙面。

House --> extrude(5+rand(20))
          comp(f) { side : Facade | top : Roof }

Roof --> roofGable(20) color(1,0,0)

Facade --> split(y) { ~5 : split(x) 
                    { ~5 : Tile }* }*

Tile --> case inside(inter) : NIL
         case touches(inter) : Wall.
         else : setback(1) { all : Wall. 
              | remainder : NIL }
相互遮挡

标注

在本示例中,将 Field 规则应用于一个矩形初始形状(内部遮挡)。 除了房屋之外,还在形状上分散随机封闭树资产。 系统会自动为每个树资产(叶形状)创建其他遮挡物形状。 可以在房屋的 Tile 规则中将目标选择器更改为 intra

Field --> Ground
          scatter(surface, rand(500), uniform) 
                 { Place }
		  
Ground --> color(0,0.5,0)

Place --> 1% : PlaceHouse else : PlaceRandomTree

PlaceHouse --> r(0,rand(180),0)
               primitiveQuad(10+rand(10), 
                             10+rand(10))
               House
			   
PlaceTree --> i(fileRandom("/assets/*.obj"))

Tile --> case inside(intra) : NIL
         case touches(intra) : Wall.
         else : setback(1) { all : Wall. | 
                remainder : NIL }
已应用 Field 规则

在这里,overlaps 用于避免与树资产重叠。 记住移除所有相互重叠的树的方法,尽管有时可能移除一部分树资产即可。 此外,需要记住一些窗户不会显示,因为它们与插入的树资产生成的遮挡物形状接触。 此示例演示了遮挡查询如何针对在条件 false 实例(无论是否遮挡都会插入所有树资产)中创建的遮挡物形状进行测试。

PlaceTree --> i(fileRandom("/assets/*.obj"))
              CheckOverlap

CheckOverlap --> case overlaps(intra) : NIL
                 else : Tree.
使用重叠的 label 操作

在此示例中,使用 label 操作将房屋块标注为 "block"。 此标注用于 Tile 规则的遮挡查询。 现在,将仅针对与请求的标注匹配的遮挡物形状测试窗户,而不针对自动生成的树资产遮挡物形状。

House --> extrude(5+rand(20))
          label("block")
          comp(f) { side : Facade | top : Roof }

Tile --> case inside(all, "block") : NIL
         case touches(all, "block") : Wall.
         else : setback(1) { all : Wall. | 
                             remainder : Window }
使用房屋块的 label 操作

标注可进一步在树的 CheckOverlap 规则的遮挡查询中使用。 因此,树资产将针对房屋块进行检查,而不是针对彼此进行。

CheckOverlap --> case overlaps(intra, "block") : 
                               NIL
                 else : Tree.
使用 CheckOverlap 的 label 操作

混凝土示例

我们将了解混凝土示例。 下图显示了一个建筑物模型。 首先,规则使用细分分割操作生成了 U 形体量模型。 因此,侧翼的几何与主体的几何接触,并生成不切实际的相交窗户。 在下图中,左侧模型中未使用遮挡查询;在中间,遮挡的窗户为红色;在右侧,删除了遮挡的窗户。

不同遮挡阶段的模型

用于构造窗户的规则如下所示:

WindowOpening --> Sill s('1,'1,windowSetback) t(0,0,'-1) [ i(openbox) Wall ] Window

规则首先调用窗台生成,然后将范围大小设置为窗户退缩深度并相应地平移范围。 之后,插入开箱资产以对窗户孔洞侧面的墙面进行建模。 最后会调用实际的窗户生成。

为了使此规则对遮挡作出反应,我们添加了 touches 条件:

WindowOpening-->
  case touches(intra) : Wall
  else : Sill s('1,'1,windowSetback) t(0,0,'-1) [ i(openbox) Wall ] Window

现在,如果 WindowOpening 形状的几何(即由典型的立面分割规则生成的矩形面)与另一个形状几何接触,该规则仅调用 Wall 规则而不创建窗户。 否则,会像以前一样应用该规则。 上图在右侧显示了生成的建筑物模型。