🌓
搜索
 找回密码
 立即注册

【谁在阻止你生成面?】寻找SketchUp中的线头

admin 2022-9-12 19:42:23 136319

是否有过这样的经历?一个多段线段组成的环形,画一个对角线只有一半生成平面,在剩下的部分继续画线,又是只有一半生成了面,如此地持续下去,在不断的放大中或许终于完成了整个平面,随后开始删除平面上的“辅助线”。这种情况估计很多SU玩家都经历过,并且通常出现在CAD导入的底平面线稿中,圆弧又是其中的重灾区。


在绘制一条线段后,SU会自己判断是否需要创建新的平面或是分割旧的平面,但是存在下面这种情况会使得SU认为不要创建平面,如下图所示,一个在同一平面的闭合环状多段线如果其内部没有与这个多段线相连的线段则可以生成平面,如果同一平面的环状多段线内部出现了与之相连的线头,则不会生成。了解了这一点之后我们就有办法解决大部分不能生成面的问题了。



但是通常这样的线头是非常细小的,这才致使SU玩家不容易发现他们,而上演无限切割的“喜剧”。所以下面将提供一个发现这些线头的方法。


一个环状多段线是首尾相连的线段组成的,而这些线头有一端是“悬空”的,或者说这些线头的其中一个端点只连接有这一条线段,所以只要找到模型中所有符合上面分析出来条件的线段,并清除掉,就可以帮助解决不能产生面的方法。


SketchUp中一个线段是一个对象,通过这个对象可以访问它的端点,又可以通过一个具体的端点访问它所连接的线段。所以在ruby脚本中需要用到线段类(Edge)和端点类(Vertex)这两个实体类(Entity)。而这些实体储存在一个实体容器(Entities)中,SU模型中的所有可见的要素都囊括在内,每一个线段每一个面都可以从这个容器中获得。以下是初步的使用方法,具体的使用方法可能会有更加系统的教程,下面这一小段代码示例可以先跳过。


ents=Sketchup.active_model.entities#将SU模型的容器赋值给ents,#以后ents这个符号就表示整个SU模型了
ents[0]#实体的容器也可以被理解成一个数组(或者说列表)#所以可以用[i]的格式来表示其中的第几个实体#但是我们并不能知道具体哪一个实体在第几个#所以通常的方法是枚举他们,#也就是使用each{|var|block}的方法ents.each{|i|f(i)}#将模型中的每一个元素进行一个f操作,#其中i是一个迭代变量,表示每一个实体#关于ruby的语法的入门个人推荐这个网站:# https://www.runoob.com/ruby/ruby-tutorial.html
ents[0].typename#这将返回第一个实体的类型名称,#比如说返回结果是"Edge"(边线)ents[0].length#在如果ents[0]是边线的话,#那么就可以通过这个方法查看或是引用它的长度ents[0].vertices[0]#返回这个边线的第一个端点ents[0].vertices[1]#返回这个边线的第二个端点(当然也是最后一个)(ents[0].vertices[1]).typename#端点的类型也就自然是"Vertex"(端点类)(ents[0].vertices[1]).edges#返回第二个端点连接的所有边线,#返回也是一个数组(列表),#也可以使用[i]访问(ents[0].vertices[1]).edges.length#这将返回这个端点有几个连接的线段ents[0].erase!#这将删除第一个实体,#不要在迭代过程中使用这个方法,#否则实体的下标会混乱


下面是实现的方法,第一个函数将符合条件的线头全部删除,第二个函数则是将符合条件的全部选中,每一步的注释解释每一行代码在做什么:


module Apiglio
#实体容器的简写方法定义  def Apiglio.ents Sketchup.active_model.entities  end  #选区容器的简写方法定义  def Apiglio.sels    Sketchup.active_model.selection end #删除影响成面的线头  def Apiglio.delete_thrum    list=[]#临时建立一个空列表用于储存需要删除的线头    Apiglio.ents.each{|i|#实体容器中的每一个实体都执行如下代码      if i.typename=="Edge" then#如果是实体类型是"边线" if i.vertices[0].edges.length==1 or i.vertices[1].edges.length==1 then          list<<i#如果符合两个端点中有一个端点所连接的线段只有一个那么就将这个实体记录在临时列表中 end end } list.each{|i|if i.deleted? then else i.erase! end}    #将临时列表中的所有实体全部删除  end#选择影响成面的线头 def Apiglio.select_thrum    Apiglio.sels.clear#取消选择 Apiglio.ents.each{|i| if i.typename=="Edge" then if i.vertices[0].edges.length==1 or i.vertices[1].edges.length==1 then          Apiglio.sels.add i#将符合条件的实体加入选区 end end }  endend


保存成apiglio.rb后将文件放在Tool文件夹中,之后在Ruby控制台输入以下内容即可查找线头:


load "apiglio.rb"Apiglio.select_thrum


以下是执行的效果:



这种方法可以找到符合条件的线头,但是当删除这些线头时,有可能出现新的线头,所以最好是多次使用这个方法。另外,这种方法可以找到不能生成面的“害群之马”,但是如何处理应该要有更好的方式,而不应该是简单地删除,所以后续还会有关于生成面的其他解决方式。


扫一扫

109311.jpg

0 回复

高级模式
游客
返回顶部