OpenSCAD用戶手冊/其他語言特性
特殊變量
編輯特殊變量為向模塊與函數傳遞參數提供了一種替代方法。所有的用戶或OpenSCAD自身通過在變量前加入'$'來定義特殊變量,這與lisp中的特殊變量定義方式相似。Modules and function see all outside variables in addition to those passed as arguments or defined internally.
常規變量的賦值發生在編譯時,因此,對於所有調用而言其值是靜態的。
Special variables pass along their value from within the scope (see scope of variables) from which the module or function is called. This means that special variables can potentially have a different value each time a module or function is called.
regular = "regular global"; $special = "special global"; module show() echo(" in show ", regular," ", $special ); echo (" outside ", regular," ", $special ); // ECHO: " outside ", "regular global", " ", "special global" for ( regular = [0:1] ){ echo("in regular loop ", regular," ", $special ); show();} // ECHO: "in regular loop ", 0, " ", "special global" // ECHO: " in show ", "regular global", " ", "special global" // ECHO: "in regular loop ", 1, " ", "special global" // ECHO: " in show ", "regular global", " ", "special global" for ( $special = [5:6] ){ echo("in special loop ", regular," ", $special ); show();} // ECHO: "in special loop ", "regular global", " ", 5 // ECHO: " in show ", "regular global", " ", 5 // ECHO: "in special loop ", "regular global", " ", 6 // ECHO: " in show ", "regular global", " ", 6 show(); // ECHO: " in show ", "regular global", " ", "special global"
This is useful when multiple arguments need to be passed thru several layers of module calls.
Several special variables are already defined by OpenSCAD.
$fa, $fs 與 $fn
編輯特殊變量$fa, $fs 與 $fn控制着用於生成弧的細分平面數量:
$fa為片段的最小角度。即使是一個再巨大的圓形,也不能通過此值而將其劃分為多於360個片段。此特殊變量的默認值為12 (即,整個圓形分為30個片段)。其最小值為0.01。若企圖將其設置為小於0.01的值,會產生一個警告。
$fs為片段的最小尺寸。Because of this variable very small circles have a smaller number of fragments than specified using $fa. 此特殊變量的默認值為2。其最小值為0.01。若企圖將其設置為小於0.01的值,會產生一個警告。
$fn通常為0。當此變量大於0時,則忽略另外兩個變量($fa, $fs),且以此值作為片段數量來渲染整個圓形。其默認值為0。
片段數量越多,佔用的內存與CPU也就越多,較大值會令大多數系統跪掉。 Depending on the design, $fn values, and the corresponding results of $fa & $fs, should be kept small, at least until the design is finalised when it can be increased for the final result. A $fn over 100 is not recommended or only for specific circumstances, and below 50 would be advisable for performance.
TIP: If you want to create a circle/cylinder/sphere which has a axis aligned integer bounding box (i.e. a bounding box that has integral dimensions, and an integral position) use a value of $fn that is divisible by 4.
當採用$fa與$fs來確定一個圓形的片段數量時,OpenSCAD使用的片段從不會少於5個。
以下是計算圓形中片段數量的C代碼:
int get_fragments_from_r(double r, double fn, double fs, double fa) { if (r < GRID_FINE) return 3; if (fn > 0.0) return (int)(fn >= 3 ? fn : 3); return (int)ceil(fmax(fmin(360.0 / fa, r*2*M_PI / fs), 5)); }
Or you can embed this OpenSCAD version in your code to work out what's going on, you need to set r= to your size
echo(n=($fn>0?($fn>=3?$fn:3):ceil(max(min(360/$fa,r*2*PI/$fs),5))),a_based=360/$fa,s_based=r*2*PI/$fs);
Spheres are first sliced into as many slices as the number of fragments being used to render a circle of the sphere's radius, and then every slice is rendered into as many fragments as are needed for the slice radius. You might have recognized already that the pole of a sphere is usually a pentagon. This is why.
The number of fragments for a cylinder is determined using the greater of the two radii.
The method is also used when rendering circles and arcs from DXF files. The variables have no effect when importing STL files.
You can generate high resolution spheres by resetting the $fX values in the instantiating module:
$fs = 0.01; sphere(2);
或簡單地通過傳入特殊變量作為參數:
sphere(2, $fs = 0.01);
您甚至可以直接為特殊變量乘以某個值而非將其重置:
sphere(2, $fs = $fs * 0.01);
$t
編輯$t變量用於製作動畫。如果您通過設置view->animate開啟動畫,並指定"FPS(幀率)"以及"Steps(步長)","Time"字段顯示的就是$t的當前值。掌握了這些信息,便能令您的設計以動畫效果展示出來。The design is recompiled every 1/"FPS" seconds with $t incremented by 1/"Steps" for "Steps" times, ending at either $t=1 or $t=1-1/steps.
如果選中"Dump Pictures(轉存圖片)",那麼就會在.scad文件所在的相同目錄下創建一系列圖片,此功能會利用以下$t值,並將圖像保存在下列文件中:
- $t=0/Steps filename="frame00001.png"
- $t=1/Steps filename="frame00002.png
- $t=2/Steps filename="frame00003.png"
- . . .
- $t=1-3/Steps filename="frame<Steps-2>.png"
- $t=1-2/Steps filename="frame<Steps-1>.png"
- $t=1-1/Steps filename="frame00000.png"
或者,對於其他Steps步長值,它將按以下模式執行:
- $t=0/Steps filename="frame00001.png"
- $t=1/Steps filename="frame00002.png
- $t=2/Steps filename="frame00003.png"
- . . .
- $t=1-3/Steps filename="frame<Steps-2>.png"
- $t=1-2/Steps filename="frame<Steps-1>.png"
- $t=1-1/Steps filename="frame<Steps-0>.png"
- $t=1-0/Steps filename="frame00000.png"
Which pattern it chooses appears to be an unpredictable, but consistent, function of Steps. For example, when Steps=4, it follows the first pattern, and outputs a total of 4 files. When Steps=3, it follows the second pattern, and also outputs 4 files. It will always output either Steps or Steps+1 files, though it may not be predictable which. When finished, it will wrap around and recreate each of the files, looping through and recreating them forever.
$vpr, $vpt 與 $vpd
編輯這三個特殊變量包含當前渲染時的視口旋轉、視口平移與攝像機距離三種信息。移動視口並不會影響它們的值(wconly:??)。在展示動畫期間會在每幀都更新它們的值。
- $vpr表示旋轉
- $vpt表示平移(即此值不受旋轉或縮放操作影響)
- $vpd表示攝像機距離 [請注意: 需要使用版本 2015.03]
示例
cube([10, 10, $vpr[0] / 10]);
如果開啟動畫循環(無需使用$t變量),這段代碼將使立方體隨觀察視角改變大小。
You can also make bits of a complex model vanish as you change the view.
All three variables are writable but only assignments at the top-level of the main file will have an effect on the viewport. [請注意: 需要使用版本 2015.03]
示例
$vpr = [0, 0, $t * 360];
which allows a simple 360 degree rotation around the Z axis in animation mode.
The menu command Edit - Paste Viewport Rotation/Translation copies the current value of the viewport, but not the current $vpr or $vpt.
$preview
編輯[請注意: 需要使用版本 2019.05]
當處於OpenCSG預覽模式(F5)下,$preview為true。在處於渲染模式(F6)下,$preview為false。
This can, for example, be used to reduce detail during preview to save time, without losing detail in the final rendered result:
$fn = $preview ? 12 : 72; sphere(r = 1);
請注意,渲染模塊不會影響$preview:
render(){ $fn = $preview ? 12 : 72; sphere(r = 1); }
Another use could be to make the preview show an assembly view and the render generate just the printed parts laid out for printing.
If printed parts need extra features that are removed post printing, for example support for suspended holes, then the preview can omit these to show the finished part after post processing.
When OpenSCAD is run from the command line $preview is only true when generating a PNG image with OpenCSG. It is false when generating STL, DXF and SVG files with CGAL. It is also false when generating CSG and ECHO files. This may or may not be what you want, but you can always override it on the command line like any other variable with the -D option.
echo語句
編輯此函數會在編譯窗口(又名控制台)中打印特定內容。有助於調試代碼。參見字符串函數 str().
此函數顯示的數值經四捨五入保留5位有效數字。
OpenSCAD控制台支持HTML標記語言的一個子集。細節請見Qt Docs。
It can be handy to use 'variable=variable' as the expression to easily label the variables, see the example below.
用例
編輯用例:
my_h=50; my_r=100; echo("This is a cylinder with h=", my_h, " and r=", my_r); echo(my_h=my_h,my_r=my_r); // shortcut cylinder(h=my_h, r=my_r); // echo("Hello Qt!");
工作枱中顯示的結果為:
ECHO: "This is a cylinder with h=", 50, " and r=", 100 ECHO: my_h = 50, my_r = 100 ECHO: "Hello Qt!"
四捨五入示例
編輯針對四捨五入設置的示例:
a=1.0;
b=1.000002;
echo(a);
echo(b);
if(a==b){ // 尽管回显结果相同,但是二值仍有差别
echo ("a==b");
}else if(a>b){
echo ("a>b");
}else if(a<b){
echo ("a<b");
}else{
echo ("???");
}
小數與大數示例
編輯c=1000002;
d=0.000002;
echo(c); //1e+06
echo(d); //2e-06
HTML
編輯HTML工作示例:
echo("<h1>Heading</h1>");
echo("<b>Bold</b> <i>italic</i> <big>big</big>");
echo("i<sub>1</sub><sup>2<sup>");
echo("<font color='red'>red</font> <font color='green'>green</font> <font color='blue'>blue</font>");
不會生效的代碼示例:
echo("<img src='http://www.openscad.org/assets/img/logo.png'></img>");
echo("<a href='http://en.wikibooks.org/'>wikibooks</a>");
請注意:可以複製輸出再將其粘貼到OpenOffice中,圖片與連結在裏面都可正常工作。
echo函數
編輯[請注意: 需要使用版本 2019.05]
Echo can be used in expression context to print information while the function/expression is evaluated. The output is generated before the expression evaluation to allow debugging of recursive functions.
示例
a = 3; b = 5; // echo() prints values before evaluating the expression r1 = echo(a, b) a * b; // ECHO: 3, 5 // using let it's still easy to output the result r2 = let(r = 2 * a * b) echo(r) r; // ECHO: 30 // use echo statement for showing results echo(r1, r2); // ECHO: 15, 30
A more complex example shows how echo() can be used in both descending and ascending path of a recursive function. The result() helper function is a simple way to output the value of an expression after evaluation.
Example printing both input values and result of recursive sum()
v = [4, 7, 9, 12]; function result(x) = echo(result = x) x; function sum(x, i = 0) = echo(str("x[", i, "]=", x[i])) result(len(x) > i ? x[i] + sum(x, i + 1) : 0); echo("sum(v) = ", sum(v)); // ECHO: "x[0]=4" // ECHO: "x[1]=7" // ECHO: "x[2]=9" // ECHO: "x[3]=12" // ECHO: "x[4]=undef" // ECHO: result = 0 // ECHO: result = 12 // ECHO: result = 21 // ECHO: result = 28 // ECHO: result = 32 // ECHO: "sum(v) = ", 32
render
編輯Forces the generation of a mesh even in preview mode. Useful when the boolean operations become too slow to track.
Needs description.
用例:
render(convexity = 2) difference() { cube([20, 20, 150], center = true); translate([-10, -10, 0]) cylinder(h = 80, r = 10, center = true); translate([-10, -10, +40]) sphere(r = 10); translate([-10, -10, -40]) sphere(r = 10); }
surface
編輯Surface reads Heightmap information from text or image files.
參數
- file
- String. The path to the file containing the heightmap data.
- center
- Boolean. This determines the positioning of the generated object. If true, object is centered in X- and Y-axis. Otherwise, the object is placed in the positive quadrant. Defaults to false.
- invert
- Boolean. Inverts how the color values of imported images are translated into height values. This has no effect when importing text data files. Defaults to false. [請注意: 需要使用版本 2015.03]
- convexity
- Integer. The convexity parameter specifies the maximum number of front sides (back sides) a ray intersecting the object might penetrate. This parameter is only needed for correctly displaying the object in OpenCSG preview mode and has no effect on the final rendering.
文本文件格式
編輯The format for text based heightmaps is a matrix of numbers that represent the height for a specific point. Rows are mapped to the Y-axis, columns to the X axis. The numbers must be separated by spaces or tabs. Empty lines and lines starting with a # character are ignored.
圖片
編輯[請注意: 需要使用版本 2015.03]
Currently only PNG images are supported. Alpha channel information of the image is ignored and the height for the pixel is determined by converting the color value to Grayscale using the linear luminance for the sRGB color space (Y = 0.2126R + 0.7152G + 0.0722B). The gray scale values are scaled to be in the range 0 to 100.
示例
編輯示例1:
//surface.scad surface(file = "surface.dat", center = true, convexity = 5); %translate([0,0,5])cube([10,10,10], center =true);
#surface.dat 10 9 8 7 6 5 5 5 5 5 9 8 7 6 6 4 3 2 1 0 8 7 6 6 4 3 2 1 0 0 7 6 6 4 3 2 1 0 0 0 6 6 4 3 2 1 1 0 0 0 6 6 3 2 1 1 1 0 0 0 6 6 2 1 1 1 1 0 0 0 6 6 1 0 0 0 0 0 0 0 3 1 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0
結果:
示例2:
// example010.dat generated using octave: // d = (sin(1:0.2:10)' * cos(1:0.2:10)) * 10; // save("example010.dat", "d"); intersection() { surface(file = "example010.dat", center = true, convexity = 5); rotate(45, [0, 0, 1]) surface(file = "example010.dat", center = true, convexity = 5); }
示例3:
[請注意: 需要使用版本 2015.03]
// 示例 3a scale([1, 1, 0.1]) surface(file = "smiley.png", center = true);
// 示例 3b scale([1, 1, 0.1]) surface(file = "smiley.png", center = true, invert = true);
示例4:
[請注意: 需要使用版本 2015.03]
// 示例4 surface(file = "BRGY-Grey.png", center = true, invert = false);
-
PNG測試文件
-
生成的3D表面
search
編輯The search() function is a general-purpose function to find one or more (or all) occurrences of a value or list of values in a vector, string or more complex list-of-list construct.
查找函數的用法
編輯- search( match_value , string_or_vector [, num_returns_per_match [, index_col_num ] ] );
查找函數的參數
編輯- match_value
- Can be a single string value. Search will loop over the characters in the string and search for each one in the second argument. The second argument must be a string or a list of lists (this second case is not recommended). The search function does not search for substrings.
- Can be a single numerical value.
- Can be a list of values. The search function will search for each item on the list.
- To search for a list or a full string give the list or string as a single element list such as ["abc"] to search for the string "abc" (See Example 9) or [[6,7,8]] to search for the list [6,7,8]. Without the extra brackets search will look separately for each item in the list.
- If match_value is boolean then search returns undef.
- string_or_vector
- The string or vector to search for matches.
- If match_value is a string then this should be a string and the string is searched for individual character matches to the characters in match_value
- If this is a list of lists, v=[[a0,a1,a2...],[b0,b1,b2,...],[c0,c1,c2,...],...] then search looks only at one index position of the sublists. By default this is position 0, so the search will look only at a0, b0, c0, etc. The index_col_num parameter changes which index is searched.
- If match_value is a string and this parameter is a list of lists then the characters of the string are tested against the appropriate index entry in the list of lists. However, if any characters fail to find a match a warning message is printed and that return value is excluded from the output (if num_returns_per_match is 1). This means that the length of the output is unpredictable.
- num_returns_per_match (default: 1)
- By default, search only looks for one match per element of match_value to return as a list of indices
- If num_returns_per_match > 1, search returns a list of lists of up to num_returns_per_match index values for each element of match_value.
- See Example 8 below.
- If num_returns_per_match = 0, search returns a list of lists of all matching index values for each element of match_value.
- See Example 6 below.
- index_col_num (default: 0)
- As noted above, when searching a list of lists, search looks only at one index position of each sublist. That index position is specified by index_col_num.
- See Example 5 below for a simple usage example.
Search Usage Examples
編輯- See example023.scad included with OpenSCAD for a renderable example.
Index values return as list
編輯Example | Code | Result |
---|---|---|
1 |
|
[0] |
2 |
|
[] |
3 |
|
[[0,4]] |
4 |
|
[[0,4]] (see also Example 6 below) |
Search on different column; return Index values
編輯示例5:
data= [ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",3] ]; echo(search(3, data)); // Searches index 0, so it doesn't find anything echo(search(3, data, num_returns_per_match=0, index_col_num=1));
輸出:
ECHO: [] ECHO: [2, 8]
對一組值進行搜索
編輯示例6: Return all matches per search vector element.
data= [ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ]; search("abc", data, num_returns_per_match=0);
Returns:
[[0,4],[1,5],[2,6]]
示例7: Return first match per search vector element; special case return vector.
data= [ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ]; search("abc", data, num_returns_per_match=1);
Returns:
[0,1,2]
示例8: Return first two matches per search vector element; vector of vectors.
data= [ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ]; search("abce", data, num_returns_per_match=2);
Returns:
[[0,4],[1,5],[2,6],[8]]
Search on list of strings
編輯示例9:
lTable2=[ ["cat",1],["b",2],["c",3],["dog",4],["a",5],["b",6],["c",7],["d",8],["e",9],["apple",10],["a",11] ]; lSearch2=["b","zzz","a","c","apple","dog"]; l2=search(lSearch2,lTable2); echo(str("Default list string search (",lSearch2,"): ",l2));
Returns
ECHO: "Default list string search (["b", "zzz", "a", "c", "apple", "dog"]): [1, [], 4, 2, 9, 3]"
Getting the right results
編輯// workout which vectors get the results v=[ ["O",2],["p",3],["e",9],["n",4],["S",5],["C",6],["A",7],["D",8] ]; // echo(v[0]); // -> ["O",2] echo(v[1]); // -> ["p",3] echo(v[1][0],v[1][1]); // -> "p",3 echo(search("p",v)); // find "p" -> [1] echo(search("p",v)[0]); // -> 1 echo(search(9,v,0,1)); // find 9 -> [2] echo(v[search(9,v,0,1)[0]]); // -> ["e",9] echo(v[search(9,v,0,1)[0]][0]); // -> "e" echo(v[search(9,v,0,1)[0]][1]); // -> 9 echo(v[search("p",v,1,0)[0]][1]); // -> 3 echo(v[search("p",v,1,0)[0]][0]); // -> "p" echo(v[search("d",v,1,0)[0]][0]); // "d" not found -> undef echo(v[search("D",v,1,0)[0]][1]); // -> 8
OpenSCAD版本
編輯version()與version_num()函數會返回OpenSCAD的版本號。
- version()函數以向量的形式返回OpenSCAD的版本,例如[2011, 09, 23]
- version_num()函數以數值的形式返回OpenSCAD的版本,例如 20110923
parent_module(n) 與 $parent_modules
編輯$parent_modules contains the number of modules in the instantiation stack. parent_module(i) returns the name of the module i levels above the current module in the instantiation stack. The stack is independent of where the modules are defined. It's where they're instantiated that counts. This can be used to e.g. build BOMs.
示例:
module top() { children(); } module middle() { children(); } top() middle() echo(parent_module(0)); // prints "middle" top() middle() echo(parent_module(1)); // prints "top"
assert
編輯[請注意: 需要使用版本 2019.05]
參見
Assert evaluates a logical expression. If the expression evaluates to false, the generation of the preview/render is stopped with an error. A string representation of the expression and, if given, the message is output to the console.
參數
- condition
- Expression. The expression to be evaluated as check for the assertion.
- message
- String. Optional message to be output in case the assertion failed.
示例
編輯The simplest example is a simple assert(false);
, e.g. in a file named assert_example1.scad
.
cube();
assert(false);
sphere();
// ERROR: Assertion 'false' failed in file assert_example1.scad, line 2
This example has little use, but the simple assert(false);
can be used in code sections that should be unreachable.
檢查參數
編輯A useful example is checking the validity of input parameters:
module row(cnt = 3){
// Count has to be a positive integer greater 0
assert(cnt > 0);
for (i = [1 : cnt]) {
translate([i * 2, 0, 0]) sphere();
}
}
row(0);
// ERROR: Assertion '(cnt > 0)' failed in file assert_example2.scad, line 3
Adding message
編輯When writing a library, it could be useful to output additional information to the user in case of an failed assertion.
module row(cnt = 3){
assert(cnt > 0, "Count has to be a positive integer greater 0");
for(i = [1 : cnt]) {
translate([i * 2, 0, 0]) sphere();
}
}
row(0);
// ERROR: Assertion '(cnt > 0)': "Count has to be a positive integer greater 0" failed in file assert_example3.scad, line 2
Using assertions in function
編輯Assert returns its children, so when using it in a function you can write
function f(a, b) =
assert(a < 0, "wrong a") // assert input
assert(b > 0, "wrong b") // assert input
let (c = a + b) // derive a new value from input
assert(c != 0, "wrong c") // assert derived value
a * b; // calculate
is_undef
編輯[請注意: 需要使用版本 2019.05]
is_undef accepts one parameter. If the parameter is undef, this function returns true. If the parameter is not undef, it returns false. When checking a variable (like `is_undef(a)`), it does the variable lookup silently, meaning that is_undef(a) does not cause `WARNING: Ignoring unknown variable 'a'. `
The alternative is code like this:
if(a==undef){
//code goes here
}
or
b = (a==undef) ? true : false;
will cause
WARNING: Ignoring unknown variable 'a'.
is_undef also works for special variables, allowing for things like this:
exploded = is_undef($exploded) ? 0 : $exploded; // 1 for exploded view
legacy support
編輯For older openscad version, is_undef can be emulated with
function is_undef ( a ) = (undef == a) ;
which off-course causes warning(s), but requires no changes to code relaying on is_undef().
is_list
編輯[請注意: 需要使用版本 2019.05]
echo("returning true");
echo(is_list([]));
echo(is_list([1]));
echo(is_list([1,2]));
echo(is_list([true]));
echo(is_list([1,2,[5,6],"test"]));
echo("--------");
echo("returning false");
echo(is_list(1));
echo(is_list(1/0));
echo(is_list(((1/0)/(1/0))));
echo(is_list("test"));
echo(is_list(true));
echo(is_list(false));
echo("--------");
echo("causing warnings:");
echo(is_list());
echo(is_list(1,2));
is_num
編輯[請注意: 需要使用版本 2019.05]
echo("a number is a number:");
echo(is_num(0.1));
echo(is_num(1));
echo(is_num(10));
echo("inf is a number:");
echo(is_num(+1/0)); //+inf
echo(is_num(-1/0)); //-inf
echo("nan is not a number:");
echo(is_num(0/0)); //nan
echo(is_num((1/0)/(1/0))); //nan
echo("resulting in false:");
echo(is_num([]));
echo(is_num([1]));
echo(is_num("test"));
echo(is_num(false));
echo(is_num(undef));
is_bool
編輯[請注意: 需要使用版本 2019.05]
echo("resulting in true:");
echo(is_bool(true));
echo(is_bool(false));
echo("resulting in false:");
echo(is_bool([]));
echo(is_bool([1]));
echo(is_bool("test"));
echo(is_bool(0.1));
echo(is_bool(1));
echo(is_bool(10));
echo(is_bool(0/0)); //nan
echo(is_bool((1/0)/(1/0))); //nan
echo(is_bool(1/0)); //inf
echo(is_bool(-1/0)); //-inf
echo(is_bool(undef));
is_string
編輯[請注意: 需要使用版本 2019.05]
echo("resulting in true:");
echo(is_string(""));
echo(is_string("test"));
echo("resulting in false:");
echo(is_string(0.1));
echo(is_string(1));
echo(is_string(10));
echo(is_string([]));
echo(is_string([1]));
echo(is_string(false));
echo(is_string(0/0)); //nan
echo(is_string((1/0)/(1/0))); //nan
echo(is_string(1/0)); //inf
echo(is_string(-1/0)); //-inf
echo(is_string(undef));