首页 文章详情

【零基础】Sketchup删除平面内边线

Apiglio | 1288 2021-09-17 03:22 0 0 0
UniSMS (合一短信)

 础  本系列将回顾和串联往期几篇文章中的部分内容,并通过具体的例子作尽可能详尽的操作介绍。其中的部分细节和特殊情况将不再重复描述,专注于 零基础  step-by-step 两个属性。




【本期导览】

〇、何谓“平面内边线”

一、原理介绍

二、代码实现

三、补充说明


〇、何谓“平面内边线”


题目所称的“平面内边线”是指“删除后不会造成平面形态破坏的边线”。根据 SketchUp 边线平面的编辑规则,可以解释成:其所连接的平面有且只有两个不同的平面,并且这两个平面方向相同


例如下图选中的两条边线,其中左侧的边线在删除后,两侧的平面会合并为一个平面,此时平面形态没有发生变化,因此符合“平面内边线”的定义。而右侧的边线删除后,其两侧的平面都会被删除,因此不符合定义。


由此可见,“平面内边线”对于保持平面形态而言是多余的,可以删除这些边线从而减小模型大小,也可以使平面更加简洁,表现更加清晰。


在建模过程中,某些特定的建模逻辑会导致“平面内边线”的产生,通常需要额外的操作删除这些边线,例如下图的情况:


如果需要保持楼梯侧面线稿的简洁,或者是需要给侧面平面赋予材质,这时就需要通过擦除工具将边线删除。擦除过程中很有可能额外删除底边或者是楼梯轮廓的边线,造成一些需要撤销的情况。因此尽管擦除这些边线非常简单,但这项工作仍然需要消耗大量精力。


因此本篇“零基础”教程就是要提供一个简便的代码,实现一次性选择这类边线图元,以达到快速选择删除的目的。


一、原理介绍


对于一个边线图元,可以通过 ruby API 获得其所连接的平面图元。而进一步可以获取平面图元的法向量。如果一条边线所连接的两个平面法向量相同或者相反(也就是两平面平行),那么在边线仅连接这两个平面时,删除此边线就会合并这两个平面。如果边线连接超过两个平面,那么显然是更复杂的情况,不符合删除的条件。


所以一个图元如果是“平面内边线”,需要满足以下三个条件:

①首先要是边线图元(Sketchup:: Edge);

②连接且只连接 2 个平面图元(Sketchup:: Face);

③所连接的两个平面图元相互平行。


之后就可以根据这三个条件来写 ruby 的布尔表达式。要检测的图元用 edg 来表示,那么:“图元是边线”表示为 edg. is_a? (Sketchup:: Edge);“边线连接两个平面”表示为 edg. faces. length == 2;“两个平面的法线相互平行”表示为 edg. faces[0]. normal. parallel? (edg. faces[1]. normal)


二、代码实现


由于以上三个条件是层层递进的,所以需要用 if 语句进行嵌套,避免代码执行错误而导致意外中止:

  if edg.is_a?(Sketchup::Edge) then    if edg.faces.length !=2 then      false    else      edg.faces[0].normal.parallel?(edg.faces[1].normal)    end  else    false  end


以上代码就是综合了三个条件的表达式,对于每一个给定的 edg 都能够返回一个布尔变量(也就是“真”和“假”)描述其是否是符合定义。之后只需要将其置于具体的操作逻辑之中即可。


例如这里采用选区来完成筛选,功能描述为:在所有选中的图元中进行判断,然后仅保留判断结果为“真”的图元。


选择需要删除“平面内边线”的模型(未打组,或在组编辑器内),复制以下代码到 ruby 控制台并执行:

sels=Sketchup.active_model.selection.to_asels.select!{|edg|  if edg.is_a?(Sketchup::Edge) then    if edg.faces.length !=2 then      false    else      edg.faces[0].normal.parallel?(edg.faces[1].normal)    end  else    false  end}Sketchup.active_model.selection.clearSketchup.active_model.selection.add(sels)


就可以看到执行代码后选区中只剩下如下的几条边线:


之后按下 Delete 键就可以轻松地删除这些边线,并且不会删除已存在的平面。至于代码中第1、2、13、14行,与选区的操作有关。第1行抄写了一份选中的图元列表,之后第2行(一直到第12行花括号处结束),依次判断每一个图元是否符合上文的三个条件,如果符合则保留(不符合则剔除)。第13行清除当前选区(取消所有选择),第14行将之前筛选的结果应用到选区。


三、补充说明


每一次删除“平面内边线”时都复制一大长串代码是不现实的,并且这样也并没有真正节省精力,因此需要将这个功能包装起来,之后用简单的、可记忆的方法名称来调用。如果只需要在本次 SU 关闭之前使用,只需要在控制台中定义局部方法即可,也就是如下的形式:

def inner_edge  #在这里复制上文的代码实现end


之后只需要在控制台中输入 inner_edge 就可以调用之前一长串代码,不过 SU 重启之后就需要重新进行定义了。


或者也可以通过保存 .rb 文件来创建自己的辅助脚本库,这样每次打开 SU 都只需要使用一次 load 指令就可以调用文件中所有定义方法。不过需要注意,文件中的方法需要定义在模块(Module)中,否则控制台无法调用(具体的方法参考往期文章)。


以下是将此方法追加到本人编写的选区辅助脚本中的方法,其中的 reselect 方法与上文例子中第1、2、13、14行代码实现的功能相同:

module Sel  def Sel.inner    Sel.reselect{|edg|      if edg.is_a?(Sketchup::Edge) then        if edg.faces.length !=2 then          false        else          edg.faces[0].normal.parallel?(edg.faces[1].normal)        end      else        false      end    }  endend


关于这个选区辅助脚本,其使用说明和脚本全文可参照此篇 [SU-2021-05]


(完)




本篇文章尽量从最浅层的内容开始解释,其中出现了边线图元、平面图元、几何平面的空间关系判断和选区读取等内容,可以参考以下几个篇目:



也可以参考更系统的教程:





本文编号:SU-2021-07


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter