ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

用 SketchUp Ruby API 自动生成展馆模型:从六边形墙体到画框阵列

用 SketchUp Ruby API 自动生成展馆模型:从六边形墙体到画框阵列

一次课程小测要求做一个旗袍展馆:正六边形室内空间、六面墙各挂一幅画、统一高度、保持画作比例,最后保存效果图视角。手工建模当然能做,但重复的墙体、画框和定位很容易出错。这次我换了个思路:用 SketchUp 的 Ruby API 把它写成可复现的建模脚本。

一、需求拆解

先把题目翻译成可计算的参数:

  • 室内空间:内切圆半径 6m 的正六边形;
  • 层高:4m;
  • 外墙厚度:0.24m;
  • 六幅画布:0.9 × 1.6m;
  • 画布底边距地:1.2m;
  • 每幅画左右居中,画框背面距墙 0.04—0.12m;
  • 画框按 PB2Crown 0.10 × 0.10m 截面;
  • 六张原图不能改变长宽比例;
  • 外墙左下方要放 3D 个人信息文字;
  • 保存一个效果图视角。

这些参数一旦确定,剩下的就是几何计算和坐标变换。

二、技术路线

我用的是一条比较“工程化”的路线:

  1. Ruby 脚本监听命令目录;
  2. 先把当前模型保存备份;
  3. 新建一个模型,按参数生成几何;
  4. 保存.skp并导出预览图;
  5. 恢复用户原来的模型。

这样即使建模脚本中途失败,也不会把正在做的模型弄丢。

三、关键实现

1. 单位换算

SketchUp Ruby API 内部长度单位是英寸。为了避免每次写* 39.37,先封装一个米转英寸的函数:

M=39.37007874015748defp3(x,y,z=0.0)Geom::Point3d.new(x*M,y*M,z*M)end

后面所有坐标都用米来写,可读性会好很多。

2. 六边形内外轮廓

内切圆半径是 6m,所以顶点半径是:

r_in=6.0r_vertex_in=r_in/Math.cos(Math::PI/6.0)

外墙厚度 0.24m,对应外轮廓的内切圆半径是 6.24m:

r_vertex_out=(r_in+0.24)/Math.cos(Math::PI/6.0)

然后按 60° 间隔生成 12 个顶点:6 个内顶点、6 个外顶点。

3. 墙体挤出

每面墙用“内边两个点 + 外边两个点”组成底面,再向上挤出 4m:

face=entities.add_face([inner_i,inner_j,outer_j,outer_i])face.reverse!ifface.normal.z<0face.pushpull(4.0*M)

这里最容易踩的坑是底面法线方向。如果法线朝下,直接pushpull会往地下挤。所以先判断normal.z,必要时reverse!。

4. 画框与画作

画框可以拆成四根 0.10 × 0.10m 的边框,围出 0.9 × 1.6m 的画布开口。画作用 SketchUp 的add_image放进一个组里:

img=frame_group.entities.add_image(image_path,p3(-w/2,-h/2,image_z),w*M,h*M)

这里有两个细节:

  • add_image的宽高也要用模型单位;
  • 原图比例不能变,所以先按w/h计算一个在画布内“等比缩放并居中”的尺寸,再用这个尺寸创建图片,而不是直接拉伸到 0.9 × 1.6。

然后把整个画框组通过Geom::Transformation.axes变换到对应墙面的局部坐标系。

5. 3D 文字与视角

个人信息用add_3d_text生成,再放到外墙左下方。最后设置相机:

eye=Geom::Point3d.new(9.0*M,-16.0*M,12.0*M)target=Geom::Point3d.new(0,0,1.35*M)camera=Sketchup::Camera.new(eye,target,Geom::Vector3d.new(0,0,1))camera.perspective=truecamera.fov=40.0model.active_view.camera=camera model.pages.add("效果图")

pages.add会把当前相机保存成场景页,下次打开模型可以直接切换到这个视角。

四、踩过的坑

  1. save_copy要求模型已经保存过
    如果当前模型是“无标题*”,save_copy会直接报错。可以先用save保存到备份路径,或者先让用户保存。

  2. 图片尺寸不是米
    add_image的宽高参数同样按模型单位解释,传0.9会得到一张很小的图,必须乘上M。

  3. 面法线决定挤出方向
    墙体、画框底面都一样,先检查法线再pushpull,能省掉很多“挤出到地下”的排查时间。

  4. 画作比例和画框尺寸是两件事
    画框可以固定 1.10 × 1.80m,画布开口固定 0.9 × 1.6m,但里面的图片要按原图比例缩放,否则人物会被拉长。

  5. 恢复现场
    自动化脚本最好先备份、再新建、最后恢复。尤其是用户正在同一个 SketchUp 里做别的东西时,这一点比脚本本身更重要。

五、结果

最终模型包含:

  • 内切圆 6m 的正六边形空间;
  • 4m 层高、0.24m 外墙;
  • 六面墙上的六幅等比画作;
  • 画布底边距地 1.2m,画框距墙 6cm;
  • 外墙左下角 3D 个人信息;
  • 保存好的“效果图”视角。

这次最大的收获不是“省了几次点击”,而是把一次性的小测变成了可复现的建模流程:参数改一改,就能生成另一个尺寸、另一种排布的展馆。


标签:SketchUp、Ruby API、自动化建模、3D 建模

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进