学习资料:Ruby 教程 | 菜鸟教程 (runoob.com)、Ruby 程序设计语言官方网站 (ruby-lang.org)
学习时长:五天
日常练习:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
学习知识点:熟悉基本语法、熟悉类和模块、熟悉Ruby的一些特性
考核内容:实现一个关于二叉排序树相关的程序
学习资料:
File: SketchUp Ruby API — SketchUp Ruby API Documentation
SketchUp/sketchup-ruby-api-tutorials: SketchUp Ruby API 教程和示例 (github.com)
ruby for sketchup(内网共享目录:\\JAVALITTERBOY\ruby for sketchup)内容
学习时长:两周
学习知识点:Sketchup实体操作(各种实体的类型以及区别特别是群组和组件)、简易参数界面、复杂dialog界面、实体属性操作、工具开发
日常练习:绘制四分之一圆柱、截面路径跟随绘制、学习Sketchup::Tool、绘制贝兹曲线工具、绘制四分之一圆柱工具、截面放样工具、开发一个简易窗体界面、熟悉SU内部的单位(长度、角度)
考核内容:三天完成指定的工具开发
%appdata%\SketchUp\SketchUp 2023\SketchUp\Plugins,sketchup启动时会加载运行load "xxxxx.rb"实现绘制贝兹曲线方法
# 贝兹曲线绘制
class Bezier
def self.bz_compute_curve(control_pts, numseg)
dt = 1.0 / numseg
return [] if control_pts.length < 3
(0..numseg).map { |i|
evaluate(control_pts, i * dt)
}
end
def self.evaluate(pts, t)
degree = pts.length - 1
t1 = 1.0 - t
fact = 1.0
n_choose_i = 1
x = pts[0].x * t1
y = pts[0].y * t1
z = pts[0].z * t1
(1...degree).each { |i|
fact = fact * t
n_choose_i = n_choose_i * (degree - i + 1) / i
fn = fact * n_choose_i
x = (x + fn * pts[i].x) * t1
y = (y + fn * pts[i].y) * t1
z = (z + fn * pts[i].z) * t1
}
x = x + fact * t * pts[degree].x
y = y + fact * t * pts[degree].y
z = z + fact * t * pts[degree].z
Geom::Point3d.new(x, y, z)
end
end
Sketchup.active_model.start_operation '绘制贝塞尔曲线', true
begin
pts = [ORIGIN, Geom::Point3d.new(15.mm, 15.mm, 0), Geom::Point3d.new(30.mm, 0, 0), Geom::Point3d.new(30.mm, 30.mm, 0)]
curve_pts = Bezier.bz_compute_curve(pts, 30)
group = Sketchup.active_model.entities.add_group
pts.each { |pt| group.entities.add_cpoint pt }
pts.each_cons(2) do |p1, p2|
group.entities.add_cline(p1, p2)
end
curve_pts.each_cons(2) do |p1, p2|
group.entities.add_line(p1, p2)
end
Sketchup.active_model.commit_operation
rescue => e
Sketchup.active_model.abort_operation
raise e
end
实现四分之一圆柱方法
# @param [Sketchup::Model/Sketchup::Group/Sketchup::ComponentInstance] group 父级实体
# @param [Geom::Point3d] center 四分之一圆的中心点
# @param [Length] radius 四分之一圆的半径
# @param [Geom::Vector3d] normal 四分之一圆的法线方向
# @param [Length] height 四分之一圆柱体的长度
def draw_one_fourth_cylinder(group, center, radius, normal, height)
end
任意绘制一个平面作为截面
任意绘制一条线(可以是多段线也可以是曲线)
选中两个实体,执行绘制脚本,将截面沿着放样路径生成模型,生成的模型需要成组
Sketchup.active_model.selection # 可以用于获取当前模型选中的内容
掌握以下知识点:
class TestTool
def activate
end
def suspend(view)
view.invalidate
end
def deactivate(view)
view.invalidate
end
def onLButtonUp(flags, x, y, view)
@pts ||= []
@pts << view.inputpoint(x, y).position
view.invalidate
end
def getMenu(menu, flags, x, y, view)
menu.add_item("完成") do
if @pts.nil? || @pts.length < 2
UI.messagebox '点击点少于两个无法绘制'
else
Sketchup.active_model.select_tool nil
Sketchup.active_model.start_operation 'draw line', true
@pts.each_cons(2) { |p1, p2|
Sketchup.active_model.entities.add_line p1, p2
}
Sketchup.active_model.commit_operation
end
end
end
def onUserText(text, view)
puts text
end
def onMouseMove(flags, x, y, view)
@move_pt = view.inputpoint(x, y).position
view.invalidate
end
def getExtents
bounds = Geom::BoundingBox.new
@pts&.each { |pt| bounds.add pt }
bounds.add @move_pt if @move_pt
bounds
end
def draw(view)
view.drawing_color = 'red'
view.line_width = 3
view.line_stipple = ''
@pts&.each_cons(2) do |p1, p2|
view.draw_line p1, p2
end
view.line_stipple = '-'
if @move_pt && @pts
view.draw_line @pts[-1], @move_pt
end
end
end
Sketchup.active_model.select_tool TestTool.new
参考API Sketchup::PickHelper
class TestTool
def onLButtonUp(flags, x, y, view)
ph = view.pick_helper
ph.do_pick(x, y)
puts "all_picked:#{ph.all_picked}"
puts "best_picked:#{ph.best_picked}"
# Sketchup::PickHelper 相关的方法都尝试使用下看看能得到什么结果
end
end
Sketchup.active_model.select_tool TestTool.new
class TranTool #< Sketchup::Tool
# @param [Sketchup::Face] face
def self.active_tool(face)
Sketchup.active_model.select_tool(self.new(face))
end
# @param [Sketchup::Face] face
def initialize(face)
@face_pts = face.outer_loop.vertices.map(&:position)
@face_pts_view = @point = nil
@trans = Geom::Transformation.new
end
def onLButtonUp(flags, x, y, view)
if @point
Sketchup.active_model.entities.add_face(@face_pts_view || @face_pts)
Sketchup.active_model.select_tool nil
else
@point = view.inputpoint(x, y).position
end
view.invalidate
end
def onMouseMove(flags, x, y, view)
pt = view.inputpoint(x, y).position
if @point
@trans = Geom::Transformation.new(@point, pt - @point) if (pt - @point).valid?
else
@trans = Geom::Transformation.new(pt, Z_AXIS)
end
@face_pts_view = @face_pts.map { |p| p.transform(@trans) }
view.invalidate
end
def draw(view)
view.drawing_color = 'black'
view.line_width = 2
# 绘制平面
@face_pts_view&.each_index do |index|
view.draw_line @face_pts_view[index - 1], @face_pts_view[index]
end
# 绘制面当前使用的tran
# 视图像素大小转成实际的长度
length = view.pixels_to_model(50, @trans.origin)
view.drawing_color = 'red'
view.draw_line @trans.origin, @trans.origin.offset(@trans.xaxis, length)
view.drawing_color = 'green'
view.draw_line @trans.origin, @trans.origin.offset(@trans.yaxis, length)
view.drawing_color = 'blue'
view.draw_line @trans.origin, @trans.origin.offset(@trans.zaxis, length)
end
end
TranTool.active_tool(Sketchup.active_model.selection[0])
绘制工具需满足以下条件
绘制过程中需要实时预览出曲线以及放样点
曲线点支持按Esc键撤销放样点

认真学习s4u_linetool代码内容
绘制工具需满足以下条件
激活工具第一步选择一个需要被放样的面,点击选择的面后就进入第二步
第二步点击放样的路径点,并预览出放样的效果(预览效果需要考虑转折点模型拼接问题)
右键完成生成放样后的模型

# 根据路径点求解每个路径点对应的面,该方法可优化(每次增加点和减少点的时候只有部分面需要更新)
# face_pts 待放样的截面点
# path_pts 放样路径点
# points_face 存放每个点对应的平面
vec = path_pts[1] - path_pts[0]
tr = Geom::Transformation.new(path_pts[0], vec) * Geom::Transformation.new(ORIGIN - face_pts[0])
points_face = [face_pts.map { |pt| pt.transform(tr) }]
# 求解角平分线所在平面
path_pts.each_cons(3) do |p1, p2, p3|
v1, v2 = (p1 - p2).normalize, (p3 - p2).normalize
# 同向点不应该出现在路径点内 添加的时候要注意判断
if v1.parallel?(v2)
plane = [p2, v1]
else
# 角平分线向量
v = v1 + v2
plane = [p2, v1 * v2 * v]
end
points_face << points_face[-1].map { |pt| Geom.intersect_line_plane([pt, v1], plane) }
end
plane = [path_pts[-1], path_pts[-1] - path_pts[-2]]
points_face << points_face[-1].map { |pt| pt.project_to_plane(plane) }
数值与长度的转换、长度与字符串之间转换、角度同理
Class: Length — SketchUp Ruby API Documentation
Class: Numeric — SketchUp Ruby API Documentation
Class: String — SketchUp Ruby API Documentation
Sketchup::Entity以及其子类都支持进行属性记录,属性结构可以理解为一个两层结构的Hash,通过字典名找到字典,在在字典中通过Key找到值。
仔细属性并尝试以下API,可以配合Sketchup官方提供的属性查看器验证自己对API的尝试
实体属性操作相关API:添加属性,删除属性,读取属性,获取实体上所有字典,获取实体上指定字典
属性字典相关API:Sketchup::AttributeDictionaries Sketchup::AttributeDictionary
属性字典名 以及 key均为字符串,属性值可以是多种数据类型(数字、字符串、数组...)虽然一些对象也支持直接存入,但是取出数据的时候是有影响的
重点熟悉以下内容
Geom,Geom::BoundingBox、Geom::Point3d、 Geom::Transformation、 Geom::Vector3d
可以参照学习ruby for sketchup目录下的run_code以及UI_DEMO
熟悉使用UI::HtmlDialog并掌握前端数据与后台数据的交互
开发一个窗口实现简单的加减乘除运算,运算一定要交给Ruby后台 不可以使用JS直接计算

学习资料:The Ruby C API (silverhammermba.github.io)、SketchUp/ruby-c-extension-examples: Ruby C extension examples (github.com)
学习时长:两周半
学习知识点:使用Ruby C API 开发Ruby下能直接使用的动态链接库、安装使用VS2022
日常练习:参照SU官方给出的案例
考核内容:三天完成指定Ruby脚本内容迁移至C Extension