开启参数类型

Switch on argument type

使用 Open SCAD,我有一个模块,如 cube(),有一个 size 参数,可以是单个值或三个值的向量。最终,我想要一个包含三个值的向量。

如果调用者传递单个值,我希望向量的所有三个值都相同。我在语言文档中没有看到任何关于检测参数类型的内容。所以我想出了这个技巧:

module my_cubelike_thing(size=1) {
  dimensions = concat(size, size, size);
  width  = dimensions[0];
  length = dimensions[1];
  height = dimensions[2];
  // ... use width, length, and height ...
}

size是单个值时,concat的结果正是我想要的:值的三个副本。

size是三值向量时,concat的结果是九值向量,而我的代码只是忽略了最后六个值。

它有效,但只是因为我在单值情况下想要的是复制该值。是否有一种通用的方法来打开参数类型并根据该类型执行不同的操作?

如果大小的类型只能是单个值或具有 3 个值的向量,则可以通过特殊值 undef 找到类型:

a = [3,5,8];
// a = 5;
if (a[0] == undef) {
    dimensions = concat(a, a, a);
    // do something
    cube(size=dimensions,center=false);
}
else {
    dimensions = a;
    // do something
    cube(size=dimensions,center=false);
}

但是赋值仅在定义它们的范围内有效, documnetation of openscad。 所以在每个子树中都需要很多代码,我更愿意在外部脚本中验证大小类型(例如 python3)并编写 openscad 代码并将变量分配给文件,该文件可以包含在openscad 文件,这里是我的简短测试代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os

# size = 20
size = [20,15,10]

if type(size) == int:
    dimensions = [size, size, size]
elif type(size) == list:
    dimensions = size
else:
    # if other types possible
    pass

with open('variablen.scad', 'w') as wObj:
    for i, v in enumerate(['l', 'w', 'h']):
        wObj.write('{} = {};\n'.format(v, dimensions[i]))

os.system('openscad ./typeDef.scad')

variablen.scad的内容:

l = 20;
w = 15;
h = 10;

和typeDef.scad可以像这样

include <./variablen.scad>;

module my_cubelike_thing() {
    linear_extrude(height=h, center=false) square(l, w);
}

my_cubelike_thing();