OpenSCAD 使用单独的脚本和库
创建和使用模块作为单独的脚本
在上一章中,了解了 OpenSCAD 最强大的功能之一 module,以及如何将其用于参数化设计。将汽车分成不同的模块,然后将它们重新组合以创建不同类型的车辆。使用模块也可以被视为一种组织的创作和构建自己的对象库的方式。轮子模块可能会用于大量设计,无需在当前设计的脚本中重新定义它,就可以随时轻松使用它会很棒。为此,需要将轮子模块定义并保存为单独的脚本。
simple_wheel.scad
在单独的脚本文件中定义 simple_wheel 模块。在同一脚本中调用 simple_wheel 模块,以便直观地看到该模块创建的对象。将脚本文件另存为名为 simple_wheel.scad 的 scad 文件。
$fa = 1;
$fs = 0.4;
module simple_wheel(wheel_radius=10, wheel_width=6) {
rotate([90,0,0])
cylinder(h=wheel_width,r=wheel_radius,center=true);
}
simple_wheel();
接下来创建一个新的小车项目
car_with_simple_wheels.scad
为小车设计创建一个新脚本。给脚本起个喜欢的名称,但需要将脚本保存在与 simple_wheel 模块相同的工作目录中。
$fa = 1;
$fs = 0.4;
wheel_radius = 8;
base_height = 10;
top_height = 10;
track = 30;
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,base_height/2+top_height/2 - 0.001])
cube([30,20,top_height],center=true);
// Front left wheel
translate([-20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
有两种方法可以在汽车设计中使用 simple_wheel.scad 脚本。使用use或者include。
示例
下面的例子是使用include同时设置wheel_radius,wheel_width
include <simple_wheel.scad>
$fa = 1;
$fs = 0.4;
wheel_radius = 8;
wheel_width = 4;
base_height = 10;
top_height = 10;
track = 30;
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,base_height/2+top_height/2 - 0.001])
cube([30,20,top_height],center=true);
// Front left wheel
translate([-20,-track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
// Front right wheel
translate([-20,track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
// Rear left wheel
translate([20,-track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
// Rear right wheel
translate([20,track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
可以发现小车中间有个轮子,这是因为include的时候会创建对象,而use不会。
示例
将include换为use试试看,发现中间不会有轮子
use <simple_wheel.scad>
use和include的区别就在这里,use不会创建对象,只是引入。所以大多数时候都是用use。
使用具有多个模块的脚本
在前面的示例中,simple_wheel.scad 脚本只有一个模块。simple_wheel 模块。
示例
在 simple_wheel.scad 脚本中添加以下模块。将 simple_wheel.scad 脚本重命名为 Wheels.scad。
module complex_wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2) {
cylinder_height=2*wheel_radius;
difference() {
// Wheel sphere
sphere(r=wheel_radius);
// Side sphere 1
translate([0,side_spheres_radius + hub_thickness/2,0])
sphere(r=side_spheres_radius);
// Side sphere 2
translate([0,- (side_spheres_radius + hub_thickness/2),0])
sphere(r=side_spheres_radius);
// Cylinder 1
translate([wheel_radius/2,0,0])
rotate([90,0,0])
cylinder(h=cylinder_height,r=cylinder_radius,center=true);
// Cylinder 2
translate([0,0,wheel_radius/2])
rotate([90,0,0])
cylinder(h=cylinder_height,r=cylinder_radius,center=true);
// Cylinder 3
translate([-wheel_radius/2,0,0])
rotate([90,0,0])
cylinder(h=cylinder_height,r=cylinder_radius,center=true);
// Cylinder 4
translate([0,0,-wheel_radius/2])
rotate([90,0,0])
cylinder(h=cylinder_height,r=cylinder_radius,center=true);
}
}
示例
小车脚本中use wheels.scad 脚本。使用 simple_wheel 模块创建前轮,使用 complex_wheel 模块创建后轮。
use <wheels.scad>
wheel_radius = 8;
wheel_width = 4;
base_height = 10;
top_height = 10;
track = 30;
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,base_height/2+top_height/2 - 0.001])
cube([30,20,top_height],center=true);
// Front left wheel
translate([-20,-track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
// Front right wheel
translate([-20,track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
// Rear left wheel
translate([20,-track/2,0])
complex_wheel();
// Rear right wheel
translate([20,track/2,0])
complex_wheel();
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
通过这个例子,可以看出脚本的名称不必与模块的名称相同,并且一个脚本可以包含多个模块。关于如何组织模块库没有正确或错误的方法。可以使用了定义不同车轮模块的 wheel.scad 脚本。或者可以将每个模块保存为单独的 *.scad 脚本。
使用 MCAD 库
MCAD 库 ( https://github.com/openscad/MCAD ) 是 OpenSCAD 自带的常用的组件库。可以通过使用相应的 OpenSCAD 脚本并调用所需的模块来使用 MCAD 库的对象。例如,有一个 box.scad 脚本,其中包含一个圆角盒子的模型。box.scad 脚本包含一个模块,可用于创建相应的盒子。你可以打开这个脚本来检查这个模块的参数是什么,然后用它在你的设计中添加圆角框。您可以使用以下脚本创建一个边长为 10、20 和 30 个单位以及圆角半径为 3 个单位的全圆框。这个非常有用,如果你玩3D打印就会发现这样做出来的模型不会划手。
complete_rounded_box.scad
use <MCAD/boxes.scad>
$fa=1;
$fs=0.4;
roundedBox(size=[10,20,30],radius=3,sidesonly=false);
通过将sidesonly 参数设置为true,您可以创建一个只有4 个圆形边的类似尺寸的盒子。
示例
use <MCAD/boxes.scad>
$fa=1;
$fs=0.4;
roundedBox(size=[10,20,30],radius=3,sidesonly=true);
box.scad 脚本位于库目录下的 MCAD 目录中。后者可以在 OpenSCAD 的安装文件夹中找到。如果希望从任何目录访问您自己的任何库,可以将其添加到库目录中。您还可以在https://www.openscad.org/libraries.html浏览其他可用的 OpenSCAD 库。GitHub[1] 和 Thingiverse[2] 上有大量可用的库。
创建更多可参数化的模块
之前的小车轮子都是连着一根轴,因此我们可以抽象出来这个模块将其组合在一起。
axle_with_simple_wheelset_from_module.scad
use <vehicle_parts.scad>
$fa = 1;
$fs = 0.4;
module axle_wheelset(wheel_radius=10, wheel_width=6, track=35, radius=2) {
translate([0,track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
axle(track=track, radius=radius);
translate([0,-track/2,0])
simple_wheel(wheel_radius=wheel_radius, wheel_width=wheel_width);
}
axle_wheelset();
不过如果我们想把轮子换一下的话,又要重新顶一个模块比如像这样
axle_with_complex_wheelset_from_module.scad
use <vehicle_parts.scad>
$fa = 1;
$fs = 0.4;
module axle_wheelset_complex(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2, track=35, radius=2) {
translate([0,track/2,0])
complex_wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2);
axle(track=track, radius=radius);
translate([0,-track/2,0])
complex_wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2);
}
axle_wheelset_complex();
可以看出这个代码有很多重复的部分,好在openscad支持这种抽象。
axle_with_simple_wheelset_from_parameterized_module.scad
use <vehicle_parts.scad>
$fa = 1;
$fs = 0.4;
module axle_wheelset(track=35, radius=2) {
translate([0,track/2,0])
children(0);
axle(track=track, radius=radius);
translate([0,-track/2,0])
children(0);
}
axle_wheelset() {
simple_wheel();
}
axle_with_large_complex_wheelset_from_parameterized_module.scad
axle_wheelset(radius=5) {
complex_wheel(wheel_radius=20);
}
可以看出children(0)是将{}中的模块传递到了另外一个模块里面去,children(N)就代表了第N个模块。这也SCAD的魅力实在。
示例
module axle_wheelset(track=35, radius=2) {
translate([0,track/2,0])
children(0);
axle(track=track, radius=radius);
translate([0,-track/2,0])
children(1);
}
axle_wheelset() {
complex_wheel();
simple_wheel();
}
有没有感觉到SCAD的强大,本章如俄罗斯套娃一样,接下的的章节会更加有趣。