OpenSCAD User Manual/その他の言語仕様
特殊変数
[編集]変数名が '$' ではじまる変数は特殊変数である。 意味はLISPの特殊変数と似ており、字句的なスコープではなく動的なスコープをとる。
すなわち、下位のサブルーチンに (引数として明示的に指定しなくとも) 引数のごとく自動的に渡されるような用途には効果的である。 通常の変数と比べてみよう。
normal=2;
module doesnt_pass_it()
{ echo(normal); }
module normal_mod()
{ doesnt_pass_it(); }
normal_mod(normal=1); //Should echo 2
$special=3; $another=5;
module passes_it()
{ echo($special, $another); }
module special_mod()
{ $another=6;
passes_it();
}
special_mod($special=4); //Should echo 4,6
したがって一度に大量の変数を渡したくないような場合には便利である。
$fa, $fs and $fn
[編集]$fa、$fs、$fn は、円弧を生成する際の辺・面の分割数を決定する。
$fa は、辺を見込む最小角度 [度] を規定する。 大きな円であっても、(360 / $fa) を超える辺の数にはならない。 デフォルトは12である (つまり円が30角型として描かれる)。 最小は0.01であり、これよりちいさいと warning が出る。
$fs は辺の長さの最小値 [mm] を規定する。 とても小さな円の場合でも、この値が最小の辺の長さを規定するため、分割数は $fa によって定められるほど細かくはならない。 デフォルトは2である。最小の値は0.01 であり、これより小さい値を設定しようとしても warning が出る。
$fn は通常0である。0より大きい場合は、$fa、$fsは無視され、 分割数は $fn となる。デフォルトは0である。
$fa と $fs が分割数として決定される場合は、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)); }
球は最初に円としてスライスされ、次に円弧が多角形に分割される。 すでにみてきたように、円柱は通常5角柱となるのは、上記のルールによる。
円柱の場合は、分割数は上面・底面の2つの半径のうち大きい方によって決まる。
この方法は、DXFファイル中の円弧のレンダリング時にも同様に適用される。
『$fなんとか』を設定し高解像度の球を描く例を挙げる。
$fs = 0.01; sphere(2);
簡略化して、下記のようにパラメータとして変数を渡すようにも書ける:
sphere(2, $fs = 0.01);
特殊変数を新たに設定するのではなく、それまでの値に倍率を掛けることもできる。
sphere(2, $fs = $fs * 0.01);
$t
[編集]The $t variable is used for animation. If you enable the animation frame with view->animate and give a value for "FPS" and "Steps", the "Time" field shows the current value of $t. With this information in mind, you can animate your design. 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.
If "Dump Pictures" is checked, then images will be created in the same directory as the .scad file, using the following $t values, and saved in the following files:
- $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"
Or, for other values of Steps, it follows this pattern:
- $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 and $vpt
[編集]These contain the current viewport rotation and translation - at the time of doing the rendering. Moving he viewport does not update them. During an animation they are updated for each frame.
- $vpr shows rotation
- $vpt shows translation (i.e. won't be affected by rotate and zoom)
It's not possible to write to them and thus change the viewport parameters (although that could be a decent enough idea).
Example
cube([10,10,$vpr[0]/10]);
which makes the cube change size based on the view angle, if an animation loop is active (which does not need to use the $t variable)
You can also make bits of a complex model vanish as you change the view.
The menu command Edit - Paste Viewport Rotation/Translation copies the current value of the viewport, but not the current $vpd or $vpt.
ユーザ定義関数
[編集]コードの可読性を上げたり再利用するために、関数 を定義することができる。
例:
my_d=20; function r_from_dia(my_d) = my_d / 2; echo("Diameter ", my_d, " is radius ", r_from_dia(my_d));
Echo 文
[編集]コンパイルウィンドウ (別名コンソール) にメッセージを表示する。デバッグに有用である。
OpenSCAD コンソールは HTML マークアップ言語をサポートする (詳細は here 参照)。
例:
my_h=50; my_r=100; echo("This is a cylinder with h=", my_h, " and r=", my_r); cylinder(h=my_h, r=my_r);
echo("<b>Hello</b> <i>Qt!</i>");
コンソール表示は下記のようになる。
ECHO:Hello Qt!
Render 文
[編集]プレビューモードでも強制的にメッシュを生成するようにできる。 ブーリアン演算が追跡するのに遅すぎる場合に有効である。
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 は Heightmap をテキストファイルまたは画像ファイルから読むための文である。
引数
- file
- 文字列。height mapデータを格納したファイルへのパス。
- center
- boolean。生成されたオブジェクトの(X, Y)平面上の原点を決定する。trueの場合は、オブジェクトの中心は座標原点になる。
falseの場合、オブジェクトは第1象限に生成される。デフォルトはfalseである。
- invert
- boolean。画像ファイル上の輝度値とZ方向の高さに対応を決定する。
テキストデータファイルの場合には意味を持たない。 デフォルトはfalseである。
- convexity
- 整数。
convexity (凸値) はオブジェクトの表面を光線が突き抜けるとした場合の交差回数の最大値である。 オブジェクトが OpenCSG で正しくプレビュー表示されるためのみに必要で、レンダリングには影響しない。
テキストファイル形式
[編集]テキスト形式のheightmapファイルは、各点の高さを並べた行列 ( (X, Y)に対するZ座標) データである。 列はY方向、行はX方向である。 数値はスペースかタブ文字で区切られている必要がある。 空行と文字『#』ではじまる行は無視される。
画像形式
[編集]現時点ではPNG形式のみサポートされている。アルファチャネル (透明) は無視され、各点の高さは、画素の輝度値である。 カラーRGB値は、sRGBの白黒変換 (Grayscale) Y = 0.2126R + 0.7152G + 0.0722B) で定義される輝度値になる。 ここで輝度値は0から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:
// 例 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);
Search
[編集]Usage Pattern:
"search" "(" ( match_value | list_of_match_values ) "," vector_of_vectors ("," num_returns_per_match ("," index_col_num )? )? ")"; match_value : ( Value::NUMBER | Value::STRING ); list_of_match_values : "[" match_value ("," match_value)* "]"; vector_of_vectors : "[" ("[" Value ("," Value)* "]")+ "]"; num_returns_per_match : int; index_col_num : int;
The following are some usage examples.
Index values return as list
[編集]Example | Code | Result |
---|---|---|
1 |
|
[0,4] |
2 |
|
[0] |
3 |
|
[] |
4 |
|
[0,4] |
Search on different column; return Index values
[編集]Example 5:
search(3,[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",3] ], 0, 1);
Returns:
[2,8]
Search on list of values
[編集]Example 6: Return all matches per search vector element.
search("abc",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ], 0);
Returns:
[[0,4],[1,5],[2,6]]
Example 7: Return first match per search vector element; special case return vector.
search("abc",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ], 1);
Returns:
[0,1,2]
Example 8: Return first two matches per search vector element; vector of vectors.
search("abce",[ ["a",1],["b",2],["c",3],["d",4],["a",5],["b",6],["c",7],["d",8],["e",9] ], 2);
Returns:
[[0,4],[1,5],[2,6],[8]]
Search on list of strings
[編集]Example 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]"