🌓
搜索
 找回密码
 立即注册

SketchUp的自动化实战 (二)获取内部空间

练少爷 2022-8-24 13:32:51 33957

之前在做光伏插件的时候用到了投影功能,

投影功能有很多应用场景,

今天我们来制作一个获取柜体 内部空间 的插件。


获取柜体内部空间▼

QXCEewZjvle7Whzn.jpg
b8Tz8Ndix6ZbdgkK.jpg

思路分析

* 通过`InputPoint.pick`获取鼠标在内部空间点击的位置;

* 通过`Model.raytest`获取当前点往XZY轴六个方向的投影面;

* 通过获取内部空间的5个投影面推断出开口面;


1、获取鼠标当前位置▼

我们定义一个工具类去实现释放鼠标左键的响应的事件,

再通过InputPoint.pick 获取点击模型上的点:

kHbdxggdHj2JTGUw.jpg

对应代码:

class InnerSpace
	# ...
  # 左键松开事件
  def onLButtonUp(_flags, x, y, view)
    # 通过视图获取点坐标
    pick_point = Sketchup::InputPoint.new
    pick_point.pick(view, x, y)
    pick_point.position
    # ...
  end
  # ...
end


2、往6个方向投影▼

再通过Model.raytest往XYZ方向投影,

收集投影线击中的物体:

TYTZ1xI3T8k6O58o.jpg

对应代码:

# 构造XYZ轴的6个方向的raytest列表,获取投影元素
# spot = pick_point.position
item_list = []
[1, -1].each do |vec|
  (0..2).each do |i|
    cu_vec = Geom::Vector3d.new(0, 0, 0)
    cu_vec[i] = vec
    item_list << model.raytest([spot, cu_vec], true)
  end
end


备注:

拾取到的点我们往面的法方向移动一点距离,

目的是为了保证有5个方向获能取到投影面。


解释一下model.raytest的用法:

js7HSnFNgZFinJe7.jpg
.raytest(ray, wysiwyg_flag = true)  Array(Geom::Point3d, Array<Sketchup::Drawingelement>)?

入参:

ray是我们构造的一条射线,

用于指定投影的方向。

wysiwyg_flag表示是否忽略隐藏的物体。


返回:

返回一个包含两个元素列表,

第一个元素是投影点,

第二个元素是投影击中物体的实体集合,

文档原话是:instance path array of the entity


比如点击一个组件ComponentInstance_a上的面face_a上的点point_a

那投影得到的对象是:**[point_a,[ComponentInstance_a,face_a]]**


3、提取内部5个投影面▼

# 解析投影元素,存储内部空间的5个面
inner_faces = []
item_list.each do |item|
  # 过滤投影得到的面
  item_faces = item[1].select { |i| i.is_a? Sketchup::Face }
  # 去除没有投影面的
  inner_faces << item_faces[0] unless item_faces.empty?
end


4、获取开口面顶点▼

这里提供一种思路:

顶点关联的面在内部面之外,说明是开口处的点(前提是开口有个厚度面)

欢迎小伙伴们交流更好的解法。

gC5th53B8CHh8ufc.jpg

对应代码:

# 通过内部空间的5个面获取开口的顶点
def get_surface_points(inner_faces)
  # 存储开口顶点集合
  vertices_list = []
  inner_faces.each do |f|
    vertices_list += f.vertices
  end
  # 所有顶点去重,获取顶点的关联面
  surface_vertices = []
  vertices_list.uniq.each do |v|
    # 顶点关联的面在内部面之外,说明是开口处的点(前提是开口有个厚度面)
    diff_face = v.faces - inner_faces
    surface_vertices << v unless diff_face.empty?
  end
  surface_vertices.map do |i|
    i.position
  end
end


总结

该能力目前已兼容组和组件,

基于该能力在获取到开口面之后,

我们应该做一些定制化的功能,

比如一键生成门板、把手等五金件。


不过笔者对设计行业了解不多,

具体是否有价值,

能应用在哪些方面等待各位小可爱去使用。


公众号回复 内部空间 获取体验插件。

x0seRgxBggRBgoZG.jpg


SU自动化实战相关文章推荐:


SU自动化探索相关文章推荐:


SU插件开发相关文章推荐:

扫一扫

0 回复

高级模式
游客
返回顶部