OpenJSCAD 使用者指南
歡迎使用 OpenJSCAD 使用者和程式設計指南。

為了提供上下文,OpenJSCAD.org 建立在 OpenJsCad (Github) 之上,它本身受到 OpenSCAD.org 的啟發,並且本質上為開發 3D 模型提供了一種程式設計師方法。 特別是,此增強功能針對為 3D 列印建立精確模型進行了調整。
OpenJSCAD 使用 OpenSCAD 的程式設計師可能會歡迎
- 能夠使用 JavaScript 程式設計概念和庫
- 能夠建立和操作 3D 形狀,以及 2D 形狀
- 支援 OpenSCAD 原始碼(大約 80% 的所有函式)
- 其他功能,以簡化向 OpenJSCAD 的過渡
繼續閱讀以瞭解有關 OpenJSCAD 的更多資訊。
還有一個 快速參考。
OpenJSCAD 可以透過訪問專案網站 openjscad.xyz 立即使用。
OpenJSCAD 展示了一個頁面,該頁面顯示了一個 3D 檢視器以及一個編輯器。

在這裡,您可以
- 使用內建編輯器線上編輯,或
- 透過您喜歡的編輯器離線編輯
您可以透過將檔案或資料夾拖放到指定區域來開始編輯。

為了使用您喜歡的編輯器,請確保選擇了自動重新載入。 任何對檔案所做的更改將自動重新載入。

注意:每個瀏覽器(Firefox、Chrome、IE 等)支援略有不同的功能。 如果您遇到問題,請嘗試使用其他瀏覽器。
OpenJSCAD 可以透過 GitHub 或 NPM 在本地安裝。 然後,您可以透過開啟“index.html”將您的瀏覽器用作本地安裝的應用程式。 要查詢 index.html 的位置,您可能需要找出 OpenJSCAD 的所在位置。 例如,如果 OpenJSCAD 安裝在 /usr/local/lib/node_modules/@jscad/openjscad 中,則
cd /usr/local/lib/node_modules/@jscad/openjscad
open index.html
將啟動您的網路瀏覽器(示例指令碼適用於 MacOs)
OpenJSCAD 可以使用 節點版本管理器 (NVM) 很容易安裝。
- 下載並安裝 NVM
- 安裝後,輸入“nvm install v6
- 然後輸入“nvm use v6”
注意:需要 Node.js 的 LTS 版本 > 6.0.0。 我們使用 Node.js 版本 6.x.x 和 7.x.x 測試 OpenJSCAD。
現在 OpenJSCAD 可以透過以下方式下載和安裝
npm install -g @jscad/openjscad
OpenJSCAD 也可以從 GitHub 輕鬆安裝。 如果要建立用於線上使用的網站,這是首選的安裝方法。
cd base-directory-of-website git clone https://github.com/jscad/OpenJSCAD.org cd OpenJSCAD.org
注意:您可能需要進行配置更改以允許訪問某些內容(例如示例)。
本地安裝後,可以透過瀏覽器開啟`index.html`訪問 OpenJSCAD。 您可以將檔案或資料夾拖放到瀏覽器中。
注意:Chrome 和其他瀏覽器在離線時不支援拖放。
您可以拖放任何示例,以及其他設計或檔案。
% cd examples % openjscad logo.jscad % openjscad logo.jscad -o test.stl % openjscad logo.jscad -of stl
它建立了 ``logo.stl`` 或 ``test.stl``。
此外,您可以匯入 OpenSCAD(.scad)、STL ASCII 或二進位制(.stl)和 AMF(.amf)檔案,並建立 .jscad、.stl(ASCII 或二進位制)、dxf 或 .amf
% openjscad example001.scad -o example001.jscad % openjscad example001.scad -o example001.stl % openjscad frog.stl -o frog.jscad % openjscad frog.stl -o frog2.stl # does actually stl -> jscad -> stl (ascii) % openjscad example001.jscad -o example001.amf % openjscad example001.jscad -of amf # creates example001.amf % openjscad example001.jscad -of stlb # creates example001.stl (binary) % openjscad example001.jscad -of stlb -o test.stl
- -o 代表輸出
- -of 代表輸出格式(jscad、stl(預設)、stla、stlb、amf、dxf)
另請參閱如何從 CLI 傳遞變數到 main()。
目前支援以下語言和檔案格式
| 格式 | 副檔名 | 網站 | 備註 |
|---|---|---|---|
| JSCAD | .jscad | openjscad.xyz | JSCAD 是一種軟體,可以使用您的瀏覽器建立 3D 實體 CAD 物件。 |
| SCAD | .scad | OpenSCAD.org | OpenSCAD 是一種軟體,用於建立 3D 實體 CAD 物件。(僅匯入) |
| STL | .stl | 維基百科:STL(檔案格式) | STL 檔案僅描述三維物件的表面幾何形狀 |
| AMF | .amf | 維基百科:AMF(檔案格式) | 增材製造檔案格式(非常實驗性) |
| DXF | .dxf | DXF(檔案格式) | 圖形交換檔案格式(僅匯出) |
| X3D | .x3d | Web3D.org | 使用 XML 表示 3D 物件的開放標準檔案格式。 |
| SVG | .svg | W3C SVG 標準 | 可縮放向量圖形格式 |
當您拖放檔案時,語言或格式根據副檔名(.jscad 等)設定。 當您開始直接使用瀏覽器進行編輯時,預設語言為 JSCAD。
您可以透過建立包含 OpenJSCAD 和設計的特殊 URL 與他人分享設計。
- http://openjscad.org/#http://openjscad.org/examples/slices/tor.jscad
- http://openjscad.org/#http://www.thingiverse.com/download:164128 (STL)
- http://openjscad.org/#http://pastebin.com/raw.php?i=5RbzVguT (SCAD)
- http://openjscad.org/#http://amf.wikispaces.com/file/view/Rook.amf/268219202/Rook.amf (AMF)
通常,設計使用 JavaScript 語言編寫。您可以在網上找到關於 JavaScript 的培訓和幫助。
建立新設計從編寫簡單的指令碼開始,這些指令碼呼叫 CSG 函式和其他特殊函式,如 OpenJSCAD 提供的函式。OpenJSCAD 執行指令碼並渲染 3D 設計以供檢視。
OpenJSCAD 遵循向函式傳遞引數的特定標準。但是,大多數引數是可選的,因為提供了預設值。
當需要 3D 向量時,可以將引數作為陣列傳遞。如果將標量(單值)傳遞給期望 3D 向量的引數,則標量將用於 x、y 和 z 值。換句話說:radius: 1 將給出 radius: [1,1,1]。
需要示例
OpenJSCAD 指令碼必須至少定義一個函式,即 main() 函式,該函式必須返回一個 CSG 物件,或一個不相互交叉的 CSG 物件陣列。
function main() {
return union(sphere(), ...); // an union of objects or
return [sphere(), ...]; // an array of non-intersecting objects
}
或者像這樣
var w = new Array();
function a() {
w.push( sphere() );
w.push( cube().translate([2,0,0]) );
}
function main() {
a();
return w;
}
但這不起作用。
var w = new Array();
w.push( sphere() ); // Note: it's not within a function (!!)
w.push( cube().translate([2,0,0]) );
function main() {
return w;
}
因為所有 CSG 建立(如 3D 原語)都必須在 main() 函式呼叫的函式內發生。
所有圓形實體都有一個 resolution 引數,它控制細分。如果將 resolution 設定為 8,則每 360 度旋轉使用 8 個多邊形。注意,增加 resolution 會大大增加渲染時間。對於球體,多邊形數量隨著使用的 resolution 呈二次方增長。如果省略 resolution 引數,則使用以下兩個全域性預設值
- CSG.defaultResolution2D
- CSG.defaultResolution3D
前者用於 2D 曲線(圓形、圓柱體),後者用於 3D 曲線(球體、3D 擴充套件)。
類似 OpenSCAD 的函式支援 fn 引數,它是近似球體的段數(預設值為 32,每個球體的總多邊形數為 fn*fn)。

可以像這樣建立立方體或盒子
cube(); // openscad like
cube(1);
cube({size: 1});
cube({size: [1,2,3]});
cube({size: 1, center: true}); // default center:false
cube({size: 1, center: [false,false,false]}); // individual axis center true or false
cube({size: [1,2,3], round: true});
CSG.cube(); // using the CSG primitives
CSG.cube({
center: [0, 0, 0],
radius: [1, 1, 1]
});
CSG.cube({ // define two opposite corners
corner1: [4, 4, 4],
corner2: [5, 4, 2]
});
CSG.roundedCube({ // rounded cube
center: [0, 0, 0],
radius: 1,
roundradius: 0.9,
resolution: 8,
});

可以像這樣建立球體
sphere(); // openscad like
sphere(1);
sphere({r: 2}); // Note: center:true is default (unlike other primitives, as OpenSCAD)
sphere({r: 2, center: true}); // Note: OpenSCAD doesn't support center for sphere but we do
sphere({r: 2, center: [false, false, true]}); // individual axis center
sphere({r: 10, fn: 100 });
sphere({r: 10, fn: 100, type: 'geodesic'}); // geodesic approach (icosahedron further triangulated)
CSG.sphere(); // using the CSG primitives
CSG.sphere({
center: [0, 0, 0],
radius: 2, // must be scalar
resolution: 128
});
如果 ``type: 'geodesic'``,則 fn 會嘗試匹配非測地線的 fn,但實際上它以 6 步遞增(例如,fn=6..11 是相同的),fn = 1 揭示了基本形式:正二十面體。
注意:建立高解析度球體,然後對其進行操作(例如,union()、intersection() 等),由於多邊形數量巨大,會減慢渲染/構建過程。

可以像這樣建立圓柱體和圓錐體
cylinder({r: 1, h: 10}); // openscad like
cylinder({d: 1, h: 10});
cylinder({r: 1, h: 10, center: true}); // default: center:false
cylinder({r: 1, h: 10, center: [true, true, false]}); // individual x,y,z center flags
cylinder({r: 1, h: 10, round: true});
cylinder({r1: 3, r2: 0, h: 10});
cylinder({d1: 1, d2: 0.5, h: 10});
cylinder({start: [0,0,0], end: [0,0,10], r1: 1, r2: 2, fn: 50});
CSG.cylinder({ //using the CSG primitives
start: [0, -1, 0],
end: [0, 1, 0],
radius: 1, // true cylinder
resolution: 16
});
CSG.cylinder({
start: [0, -1, 0],
end: [0, 1, 0],
radiusStart: 1, // start- and end radius defined, partial cones
radiusEnd: 2,
resolution: 16
});
CSG.roundedCylinder({ // and its rounded version
start: [0, -1, 0],
end: [0, 1, 0],
radius: 1,
resolution: 16
});
其中 fn 是近似圓柱體圓形輪廓的段數(預設值為 32)。

圓環面定義如下
- ri = 內半徑(預設值:1),
- ro = 外半徑(預設值:4),
- fni = 內解析度(預設值:16),
- fno = 外解析度(預設值:32),
- roti = 內旋轉(預設值:0)
torus(); // ri = 1, ro = 4;
torus({ ri: 1.5, ro: 3 });
torus({ ri: 0.2 });
torus({ fni:4 }); // make inner circle fn = 4 => square
torus({ fni:4,roti:45 }); // rotate inner circle, so flat is top/bottom
torus({ fni:4,fno:4,roti:45 });
torus({ fni:4,fno:5,roti:45 });
使用點列表和三角形或多邊形列表建立多面體。點列表是形狀的所有頂點,三角形列表是點與多面體表面的關係。

polyhedron({ // openscad-like (e.g. pyramid)
points: [ [10,10,0],[10,-10,0],[-10,-10,0],[-10,10,0], // the four points at base
[0,0,10] ], // the apex point
triangles: [ [0,1,4],[1,2,4],[2,3,4],[3,0,4], // each triangle side
[1,0,3],[2,1,3] ] // two triangles for square base
});
此外,您還可以定義 `polygons: [ [0,1,4,5], [..] ]`,而不僅僅是 `triangles:`。
您還可以以更低階的級別建立多面體
var polygons = [];
polygons.push(new CSG.Polygon([
new CSG.Vertex(new CSG.Vector3D(-5,-5,0)),
new CSG.Vertex(new CSG.Vector3D(2,2,5)),
new CSG.Vertex(new CSG.Vector3D(3,3,15))
])
);
// add more polygons and finally:
solid = CSG.fromPolygons(polygons);
``vector_text(x,y,string)`` 和 ``vector_char(x,y,char)`` 會為您提供以向量形式渲染的文字或字元的線段。

var l = vector_text(0,0,"Hello World!"); // l contains a list of polylines to be drawn
var o = [];
l.forEach(function(pl) { // pl = polyline (not closed)
o.push(rectangular_extrude(pl, {w: 2, h: 2})); // extrude it to 3D
});
return union(o);
還支援使用“\n”的多行文字,目前僅支援左對齊。如果您想深入瞭解細節,可以請求單個字元。
var c = vector_char(x,y,"A");
c.width; // width of the vector font rendered character
c.segments; // array of segments / polylines

var obj = sphere(5);
scale(2,obj); // openscad like
scale([1,2,3],obj); // ''
obj.scale([1,2,3]); // using CSG objects' built in methods

var obj = cube([5,20,5]);
rotate([90,15,30],obj); // openscad like
rotate(90,[1,0.25,0.5],obj); // ''
obj.rotateX(90); // using CSG objects' built in methods
obj.rotateY(45);
obj.rotateZ(30);
obj.rotate(rotationCenter, rotationAxis, degrees)
obj.rotateEulerAngles(alpha, beta, gamma, position)
translate([0,0,10],obj); // openscad like
obj.translate([0,0,10]); // using CSG objects' built in methods
將物件整體或軸向居中
center(true,cube()); // openscad-like all axis
center([true,true,false],cube()); // openscad-like axis-wise [x,y]
// false = do nothing, true = center axis
cube().center(); // using CSG objects' built in methods
cube().center('x','y'); // using CSG objects' built in method to center axis-wise [x,y]
center() 和 .center() 可以幫助您組合一個對稱的,在組合時(例如,從引數化設計)您不知道其完整尺寸的形狀。
var m = new CSG.Matrix4x4();
m = m.multiply(CSG.Matrix4x4.rotationX(40));
m = m.multiply(CSG.Matrix4x4.rotationZ(40));
m = m.multiply(CSG.Matrix4x4.translation([-.5, 0, 0]));
m = m.multiply(CSG.Matrix4x4.scaling([1.1, 1.2, 1.3]));
// and apply the transform:
var cube3 = cube().transform(m);
mirror([10,20,90], cube(1)); // openscad like
var cube = CSG.cube().translate([1,0,0]); // built in method chaining
var cube2 = cube.mirroredX(); // mirrored in the x=0 plane
var cube3 = cube.mirroredY(); // mirrored in the y=0 plane
var cube4 = cube.mirroredZ(); // mirrored in the z=0 plane
// create a plane by specifying 3 points:
var plane = CSG.Plane.fromPoints([5,0,0], [5, 1, 0], [3, 1, 7]);
// and mirror in that plane:
var cube5 = cube.mirrored(plane);

union(sphere({r: 1, center:true}),cube({size: 1.5, center:true})); // openscad like
可以新增多個物件,也可以新增陣列。
sphere({r: 1, center:true}).union(cube({size: 1.5, center:true})); // using CSG objects' built in methods

intersection(sphere({r: 1, center:true}),cube({size: 1.5, center:true})); // openscad like
可以將多個物件進行交集,也可以新增陣列。
sphere({r: 1, center:true}).intersect(cube({size: 1.5, center:true})); // using CSG objects' built in methods
注意 intersection()(類似 openscad)與 intersect()(函式與 CSG 物件內建方法)之間的區別。

difference(sphere({r: 1, center:true}),cube({size: 1.5, center:true})); // openscad like
可以將多個物件從第一個元素中進行差集(減去),也可以新增陣列。
sphere({r: 1, center:true}).subtract(cube({size: 1.5, center:true})); // using CSG objects' built in methods
注意:difference()(類似 openscad)與 subtract()(方法,面向物件)之間的區別。
circle(); // openscad like
circle(1);
circle({r: 2, fn:5}); // fn = number of segments to approximate the circle
circle({r: 3, center: true}); // center: false (default)
CAG.circle({center: [0,0], radius: 3, resolution: 32}); // using CSG objects' built in methods
square(); // openscad like
square(1); // 1x1
square([2,3]); // 2x3
square({size: [2,4], center: true}); // 2x4, center: false (default)
CAG.rectangle({center: [0,0], radius: [w/2, h/2]}); // CAG built ins, where w or h = side-length of square
CAG.roundedRectangle({center: [0,0], radius: [w/2, h/2], roundradius: 1, resolution: 4});
polygon([ [0,0],[3,0],[3,3] ]); // openscad like
polygon({ points: [ [0,0],[3,0],[3,3] ] });
polygon({ points: [ [0,0],[3,0],[3,3],[0,6] ], paths: [ [0,1,2],[1,2,3] ] }); // multiple paths not yet implemented
var shape1 = CAG.fromPoints([ [0,0],[5,0],[3,5],[0,5] ]); // CAG built ins
translate([2,2], circle(1)); // openscad like
rotate([0,0,90], square()); // ''
shape = center(true, shape()); // center both axis
shape = center([true,false], shape()); // center axis-wise [x]
shape = shape.translate([-2, -2]); // object methods
shape = shape.rotateZ(20);
shape = shape.scale([0.7, 0.9]);
shape = shape.center(); // center both axis
scape = shape.center('x'); // center axis-wise [x]
路徑只是一系列點,由線連線。路徑可以是開放的或封閉的(在第一個點和最後一個點之間繪製一條額外的線)。二維路徑透過 CSG.Path2D 類得到支援。二維路徑與二維 CAG 之間的區別在於,路徑是一條“細”線,而 CAG 是一個封閉區域。
路徑可以透過向建構函式提供二維座標陣列或透過各種 CSG.Path2D 成員函式來構建,這些成員函式包括
- arc(endpoint, options):返回一條圓形或橢圓曲線路徑(有關用法,請參見下面的示例)。
- appendPoint([x,y]):建立並返回一個新的 Path2D,其中包含呼叫者的點,後跟給定點。
- appendPoints([[x,y],...]):建立並返回一個新的 Path2D,其中包含呼叫者的點,後跟給定的點。[注意:截至 2016 年 8 月 13 日,此方法還會修改呼叫者;這可能是錯誤,將來可能會更改;請參閱問題:165]
- appendBezier([[x,y],...], options):建立並返回一個新的 Path2D,其中包含呼叫者的點,後跟一條以給定最後一個點結束的貝塞爾曲線;所有除最後一個點之外的給定點都是貝塞爾的控制點;一個空初始控制點意味著使用呼叫者的最後兩個點作為新貝塞爾曲線的控制點。選項可以指定 {resolution: <NN>}。
可以使用 .concat() 連線路徑,結果是新的路徑。
路徑可以透過兩種方式轉換為 CAG
- expandToCAG(pathradius, resolution) 用一個圓跟蹤路徑,實際上使路徑的線段變粗。
- innerToCAG() 建立一個由路徑包圍的 CAG。路徑應為封閉路徑。
目前,rectangularExtrude() 函式支援建立三維實體。這透過用二維矩形(直立,垂直於路徑方向)跟蹤路徑來建立一個三維形狀
var path = new CSG.Path2D([ [10,10], [-10,10] ], /* closed = */ false);
var anotherpath = new CSG.Path2D([ [-10,-10] ]);
path = path.concat(anotherpath);
path = path.appendPoint([10,-10]);
path = path.close(); // close the path
// of course we could simply have done:
// var path = new CSG.Path2D([ [10,10], [-10,10], [-10,-10], [10,-10] ], /* closed = */ true);
// We can make arcs and circles:
var curvedpath = CSG.Path2D.arc({
center: [0,0,0],
radius: 10,
startangle: 0,
endangle: 180,
resolution: 16,
});

您可以將多個二維多邊形(例如 circle()、square()、polygon())一起進行凸包運算。
var h = hull( square(10),circle(10).translate([10,10,0]) );
linear_extrude({ height: 10 }, h);

鏈式凸包是針對多個二維形狀進行的凸包的一種變體,本質上是對多個形狀進行順序凸包運算,然後將這些凸包進行並集,基於 Whosa whatsis 的想法。
chain_hull(
circle(), circle().translate([2,0,0]), ... ); // list of CAG/2D forms
var a = [];
a.push(circle());
chain_hull( a ); // array of CAG/2D forms
chain_hull({closed: true}, // default is false
[circle(),circle().translate([2,0,0]),circle().translate([2,2,0])]);
// notice that with parameter {closed:true}, hull_chain requires an array

將二維形狀拉伸成三維形狀,給定高度、扭曲(度數)和切片數(如果進行扭曲)。
// openscad like
linear_extrude({ height: 10 }, square());
linear_extrude({ height: 10, twist: 90 }, square([1,2]));
linear_extrude({ height: 10, twist: 360, slices: 50}, circle().translate([1,0,0]) );
linear_extrude({ height: 10, center: true, twist: 360, slices: 50}, translate([2,0,0], square([1,2])) );
linear_extrude({ height: 10, center: true, twist: 360, slices: 50}, square([1,2]).translate([2,0,0]) );
二維形狀的線性拉伸,可以選擇扭曲。二維形狀放置在 z=0 平面,並沿 <offset>(CSG.Vector3D)方向拉伸。最終面旋轉 <twistangle> 度。旋轉圍繞二維形狀的原點(即 x=0,y=0)進行,twiststeps 決定扭曲的解析度(應大於等於 1),返回一個 CSG 物件。
// CAG build in method
var c = CAG.circle({radius: 3});
extruded = c.extrude({offset: [0,0,10], twistangle: 360, twiststeps: 100});

透過用矩形(直立,垂直於路徑方向)跟蹤路徑來拉伸路徑,返回一個 CSG 實體。
簡化版(類似 openscad,即使 OpenSCAD 沒有提供此功能),透過 rectangular_extrude(),其中
- w:寬度(預設值:1),
- h:高度(預設值:1),
- fn:解析度(預設值:8),以及
- closed:路徑是否封閉(預設值:false)
rectangular_extrude([ [10,10], [-10,10], [-20,0], [-10,-10], [10,-10] ], // path is an array of 2d coords
{w: 1, h: 3, closed: true});
或者更低階的 rectangularExtrude(),使用以下未命名的變數
- 拉伸的寬度,在 z=0 平面
- 拉伸的高度,在 z 方向
- 解析度,角落曲線的每個 360 度的片段數
- roundEnds:如果為真,則多邊形的端點將被圓化,否則它們將是平的
// first creating a 2D path, and then extrude it
var path = new CSG.Path2D([ [10,10], [-10,10], [-20,0], [-10,-10], [10,-10] ], /*closed=*/true);
var csg = path.rectangularExtrude(3, 4, 16, true); // w, h, resolution, roundEnds
return csg;

此外,還可以使用 rotate_extrude()
// openscad-like
rotate_extrude( translate([4,0,0], circle({r: 1, fn: 30, center: true}) ) );
// using CSG objects' built in methods to translate
rotate_extrude({fn:4}, square({size: [1,1], center: true}).translate([4,0,0]) );
rotate_extrude( polygon({points:[ [0,0],[2,1],[1,2],[1,3],[3,4],[0,5] ]}) );
rotate_extrude({fn:4}, polygon({points:[ [0,0],[2,1],[1,2],[1,3],[3,4],[0,5] ]}) );
您基本上可以拉伸任何二維多邊形(圓形、正方形或多邊形)。
實體的“property”屬性可用於儲存物件的元資料,例如實體某個特定興趣點的座標。每當物件被變換(即旋轉、縮放或平移)時,屬性也會隨之變換。因此,即使對實體應用了多個變換,屬性也會繼續指向相同的興趣點。
屬性可以是任何型別,但只有支援“transform”方法的類的屬性才會被實際變換。這包括 CSG.Vector3D、CSG.Plane 和 CSG.Connector。特別是 CSG.Connector 屬性(見下文)非常有用:它們可以用來將實體連線到另一個實體的預定位置,無論當前方向如何。
甚至可以將 CSG 實體作為另一個實體的屬性。例如,這可以用於定義用於建立與物件匹配的螺釘孔的切口圓柱體。這些“實體屬性”會獲得與擁有實體相同的變換,但在 union() 等 CSG 操作的結果中將不可見。
其他型別的屬性(例如,字串)將仍然包含在變換後的實體的屬性中,但當擁有實體被變換時,屬性不會獲得任何變換。
所有基元實體都有一些預定義的屬性,例如球體的中心點(TODO:文件化)。
由 CSG 操作(union()、subtract()、intersect())產生的實體將獲得兩個源實體的合併屬性。如果存在同名屬性,則只保留其中一個。
var cube = CSG.cube({radius: 1.0});
cube.properties.aCorner = new CSG.Vector3D([1, 1, 1]);
cube = cube.translate([5, 0, 0]);
cube = cube.scale(2);
// cube.properties.aCorner will now point to [12, 2, 2],
// which is still the same corner point
// Properties can be stored in arrays; all properties in the array
// will be transformed if the solid is transformed:
cube.properties.otherCorners = [
new CSG.Vector3D([-1, 1, 1]),
new CSG.Vector3D([-1, -1, 1])
];
// and we can create sub-property objects; these must be of the
// CSG.Properties class. All sub properties will be transformed with
// the solid:
cube.properties.myProperties = new CSG.Properties();
cube.properties.myProperties.someProperty = new CSG.Vector3D([-1, -1, -1]);
CSG.Connector 類旨在簡化將兩個實體在預先確定的位置和方向上連線在一起的操作。例如,假設我們有一個表示伺服電機的 CSG 實體和一個表示伺服臂的實體:透過為它們中的每一個定義一個 Connector 屬性,我們可以輕鬆地將伺服臂連線到伺服電機在正確的位置(即電機軸)和方向(即臂垂直於軸)上,即使我們不知道它們在 3D 空間中的當前位置和方向。
換句話說,Connector 使我們能夠自由地旋轉和平移物體,而無需跟蹤它們的位置和邊界。如果第三方庫為其實體公開聯結器,則庫的使用者無需瞭解實際尺寸或形狀,只需要知道聯結器屬性的名稱。
CSG.Connector 由 3 個屬性組成
- point:一個 CSG.Vector3D,定義了 3D 空間中的連線點
- axis:一個 CSG.Vector3D,定義了連線的方向向量(在伺服電機示例中,它將指向軸的方向)
- normal:一個 CSG.Vector3D 方向向量,與軸大致垂直;這定義了連線的“12 點鐘”方向。
連線兩個聯結器時,實體將進行變換,使得 point 屬性將相同,axis 屬性將具有相同的方向(如果 mirror == true,則為相反方向),並且 normal 儘可能匹配。
聯結器可以透過兩種方法連線:CSG 實體的 connectTo() 函式將變換實體,使得兩個聯結器連線起來。或者,我們可以使用聯結器的 getTransformationTo() 方法來獲取一個變換矩陣,該矩陣將連線聯結器。如果需要對多個實體應用相同的變換,可以使用這種方法。
var cube1 = CSG.cube({radius: 10});
var cube2 = CSG.cube({radius: 4});
// define a connector on the center of one face of cube1
// The connector's axis points outwards and its normal points
// towards the positive z axis:
cube1.properties.myConnector = new CSG.Connector([10, 0, 0], [1, 0, 0], [0, 0, 1]);
// define a similar connector for cube 2:
cube2.properties.myConnector = new CSG.Connector([0, -4, 0], [0, -1, 0], [0, 0, 1]);
// do some random transformations on cube 1:
cube1 = cube1.rotateX(30);
cube1 = cube1.translate([3.1, 2, 0]);
// Now attach cube2 to cube 1:
cube2 = cube2.connectTo(
cube2.properties.myConnector,
cube1.properties.myConnector,
true, // mirror
0 // normalrotation
);
// Or alternatively:
var matrix = cube2.properties.myConnector.getTransformationTo(
cube1.properties.myConnector,
true, // mirror
0 // normalrotation
);
cube2 = cube2.transform(matrix);
var result = cube2.union(cube1);
getBounds() 函式可以用來檢索物件的邊界框,返回一個包含兩個 CSG.Vector3Ds 的陣列,指定最小 X、Y、Z 座標和最大 X、Y、Z 座標。
lieFlat() 函式將物體鋪設在 Z 表面上,使得 Z 高度最小化,並且物體圍繞 Z 軸居中。這對於 CNC 銑削非常有用,因為它允許在銑削過程中將物體變換到坯料材料的空間中。或者對於 3D 列印:它以一種可以以最少的層數列印的方式鋪設。除了 lieFlat() 函式外,還可以使用 getTransformationToFlatLying() 函式,該函式返回一個 CSG.Matrix4x4 來進行變換。
var cube1 = CSG.cube({radius: 10});
var cube2 = CSG.cube({radius: 5});
// get the right bound of cube1 and the left bound of cube2:
var deltax = cube1.getBounds()[1].x - cube2.getBounds()[0].x;
// align cube2 so it touches cube1:
cube2 = cube2.translate([deltax, 0, 0]);
var cube3 = CSG.cube({radius: [100,120,10]});
// do some random transformations:
cube3 = cube3.rotateZ(31).rotateX(50).translate([30,50,20]);
// now place onto the z=0 plane:
cube3 = cube3.lieFlat();
// or instead we could have used:
var transformation = cube3.getTransformationToFlatLying();
cube3 = cube3.transform(transformation);
return cube3;
OpenSCAD 風格
color([r,g,b], object, object2 ...); // for example, color([1,1,0],sphere());
color([r,g,b], array);
color([r,g,b,a], object, object2 ...);
color([r,g,b,a], array);
color(name, object, object2 ...); // for example, color('red',sphere());
color(name, a, object, object2 ...); // for example, color('red',0.5, sphere());
color(name, array);
color(name, a, array);
命名的顏色不區分大小寫,例如,'RED' 與 'red' 相同。
使用 CSG 物件的內建方法(r、g、b 必須在 0 到 1 之間,而不是 0 到 255)
object.setColor([r,g,b]);
object.setColor([r,g,b,a]);
object.setColor(r,g,b);
object.setColor(r,g,b,a);
object.setColor(css2rgb('dodgerblue'));
示例
color([1,0.5,0.3],sphere(1)); // openscad like
color([1,0.5,0.3],sphere(1),cube(2));
color("Red",sphere(),cube().translate([2,0,0])); // named color (case-insensitive)
sphere().setColor(1,0.5,0.3); // built in methods
sphere().setColor([1,0.5,0.3]);
有關所有可用顏色的資訊,請參見 擴充套件顏色關鍵字。

程式碼摘錄
o.push( color([1,0,0],sphere()) );
o.push( color([0,1,0],cube()) );
o.push( color([0,0,1],cylinder()) );
o.push( color("red",sphere()) );
o.push( color("green", cube()) );
o.push( color("blue", cylinder()) );
for(var i=0; i<1; i+=1/12) {
o.push( cube().setColor(hsl2rgb(i,1,0.5)) );
}

程式碼
function main() {
var o = [];
for(var i=0; i<8; i++) {
o.push(cylinder({r:3,h:20}).
setColor(
hsl2rgb(i/8,1,0.5). // hsl to rgb, creating rainbow [r,g,b]
concat(1/8+i/8) // and add to alpha to make it [r,g,b,a]
).translate([(i-3)*7.5,0,0])
);
}
o.push(color("red",cube(5)).translate([-4,-10,0]));
o.push(color("red",0.5,cube(5)).translate([4,-10,0]));
return o;
}
注意:有一些 OpenGL 透明度限制,例如,根據顏色的順序,你可能無法透過部分透明的物體看到。
以下函式用於在顏色空間之間轉換
var hsl = rgb2hsl(r,g,b); // or rgb2hsl([r,g,b]);
var rgb = hsl2rgb(h,s,l); // or hsl2rgb([h,s,l]);
var hsv = rgb2hsv(r,g,b); // or rgb2hsv([r,g,b]);
var rgb = hsv2rgb(h,s,v); // or hsv2rgb([h,s,v]);
其中
- r、g、b(紅色、綠色、藍色)
- h、s、l(色調、飽和度、亮度)
- h、s、v(色調、飽和度、值)
例如,要建立彩虹,t = 0..1 並且 .setColor(hsl2rgb(t,1,0.5))

有關示例,請參見 Tor(多色)。
a = 1, b = 2;
echo("a="+a,"b="+b);
在 JavaScript 控制檯中列印:a=1, b=2
Javascript 透過 Math 庫 提供了一些函式。此外,還提供以下與 OpenSCAD 相容的函式
sin(a); // a = 0..360
cos(a); // ''
asin(a); // a = 0..1, returns 0..360
acos(a); // ''
tan(a); // a = 0..360
atan(a); // a = 0..1, returns 0..360
atan2(a,b); // returns 0..360
ceil(a);
floor(a);
abs(a);
min(a,b);
max(a,b);
rands(min,max,vn,seed); // returns random vectors of vn dimension, seed not yet implemented
log(a);
lookup(ix,v); // ix = index, e.g. v = [ [0,100], [10,10], [20,200] ] whereas v[x][0] = index, v[x][1] = value
// return will be linear interpolated (e.g. lookup(5,[ [0,100], [10,10], [20,200] ]) == 45
pow(a,b);
sign(a); // -1, 0 or 1
sqrt(a);
round(a);
包含一個 OpenSCAD 到 OpenJSCAD 的轉換器,但以下功能尚不可用
- DXF 匯入和操作(例如 import_dxf、dxf-cross、dxf_dim 函式)。
- rotate_extrude()(注意:OpenJSCAD 支援 rotate_extrude())
- minkowski() 和 hull() 變換(注意:OpenJSCAD 支援 hull())
- 全域性變數,如 $fa、$fs
- 修飾符字元:#、 !、 %
- 列表推導,例如:list = [ for (i = [2, 3, 5, 7, 11]) i * i ];
你可以在內建編輯器中編輯 OpenSCAD 原始碼,只要確保第一行是
//!OpenSCAD
然後原始碼將以 OpenSCAD 語法顯示。
將來可能會提供其他 CAD 語言支援。
為了將你的 OpenSCAD 轉換為原生 OpenJSCAD 程式碼,請考慮以下對比。
OpenSCAD
union() {
//cube(size=[30,30,0.1],center=true);
translate([3,0,0]) cube();
difference() {
rotate([0,-45,0]) cube(size=[8,7,3],center=true);
sphere(r=3,$fn=20,center=true);
}
translate([10,5,5]) scale([0.5,1,2]) sphere(r=5,$fn=50);
translate([-15,0,0]) cylinder(r1=2,r2=0,h=10,$fn=20);
for(i=[0:19]) {
rotate([0,i/20*360,0])
translate([i,0,0])
rotate([0,i/20*90,i/20*90,0])
cube(size=[1,1.2,.5],center=true);
}
}
OpenJSCAD
function main() {
var cubes = new Array();
for(i=0; i<20; i++) {
cubes[i] = rotate([0,i/20*360,0],
translate([i,0,0],
rotate([0,i/20*90,i/20*90,0],
cube({size:[1,1.2,.5],center:true}))));
}
return union(
//cube({size:[30,30,0.1],center:true}),
translate([3,0,0],cube()),
difference(
rotate([0,-45,0], cube({size:[8,7,3],center:true})),
sphere({r:3,fn:20,center:true})
),
translate([10,5,5], scale([0.5,1,2], sphere({r:5,fn:50}))),
translate([-15,0,0], cylinder({r1:2,r2:0,h:10,fn:20})),
cubes
);
}
基本上,只要 OpenSCAD 中出現命名引數 func(a=1),就將其轉換為 func({a:1}),例如
// OpenSCAD
translate([0,0,2]) sphere(size=2,$fn=50)
// becomes OpenJSCAD
translate([0,0,2], sphere({size:2,fn:50}));
// or
sphere({size:2,fn:50}).translate([0,0,2]);

模型可以具有互動式引數,允許使用者透過熟悉的表單更改值,即輸入數字、滑動條、下拉選單等。這允許使用者更改值並建立任意數量的可能組合,從而使模型在本質上變得動態。可以建立任意數量的自定義設計,然後可以以任何支援的格式下載。
互動式引數可以透過新增一個名為 getParameterDefinitions() 的特定函式來實現。該函式可以新增到 JSCAD 指令碼中的任何位置,但必須返回一個引數定義陣列。
function getParameterDefinitions() {
return [{ name: 'width', type: 'float', initial: 10, caption: "Width of the cube:" }];
}
引數定義用於建立一個欄位集,使用者可以更改這些欄位,即選項。欄位的值將提供給 JSCAD 指令碼的 main() 函式。例如,'width' 引數的值將作為 'params.width' 屬性提供,依此類推。
function main(params) {
// custom error checking:
if(params.width <= 0) throw new Error("Width should be positive!");
var mycube = CSG.cube({radius: params.width});
return mycube();
}
所有常見的 HTML5 欄位型別都可用作互動式引數。這包括複選框(布林值)、顏色、日期、電子郵件、浮點數、整數、數字、密碼、滑塊、文字和 URL。以及兩種用於下拉選擇和分組引數的特殊引數型別。
最小引數規範僅包含 'name' 和 'type'。但是,完整的引數規範應具有 'caption' 和 'initial' 值。此外,還有 'min'、'max'、'step'、'checked'、'size'、'maxlength' 和 'placeholder',它們與特定引數型別相關。只要不斷嘗試不同的組合以獲得良好的引數規範。這是一個很好的例子。
{
name: 'width',
type: 'float',
initial: 1.5,
caption: 'Width of the thingy:',
min: 1.0,
max: 5.0,
step: 0.5
}
此外,還有 'choice' 型別,它為使用者建立下拉列表。選擇透過指定 'values' 和 'captions' 來提供。選擇的值將傳遞到模型的 main() 函式中。
{
name: 'shape',
type: 'choice',
values: ["TRI", "SQU", "CIR"], // these are the values that will be supplied to your script
captions: ["Triangle", "Square", "Circle"], // optional, these values are shown in the listbox
// if omitted, the items in the 'values' array are used
caption: 'Shape:', // optional, displayed left of the input field
initial: "SQU", // optional, default selected value
// if omitted, the first item is selected by default
// NOTE: parameter "default" is deprecated
}
一個完整的示例
function getParameterDefinitions() {
return [
{ name: 'width', type: 'float', initial: 10, caption: "Width of the cube:" },
{ name: 'height', type: 'float', initial: 14, caption: "Height of the cube:" },
{ name: 'depth', type: 'float', initial: 7, caption: "Depth of the cube:" },
{ name: 'rounded', type: 'choice', caption: 'Round the corners?', values: [0, 1], captions: ["No thanks", "Yes please"], initial: 1 }
];
}
function main(params) {
var result;
if(params.rounded == 1) {
result = CSG.roundedCube({radius: [params.width, params.height, params.depth], roundradius: 2, resolution: 32});
} else {
result = CSG.cube({radius: [params.width, params.height, params.depth]});
}
return result;
}
在 openjscad.xyz 上,有很多關於“互動式”引數的示例。有關可用引數型別和瀏覽器支援的更多資訊,請參見快速參考。
命令列介面 ``openjscad`` 可以為互動式設計傳遞引數。透過以下任一方式
key value
或
key=value
例如
% openjscad name_plate.jscad --name "Just Me" --title "Geek" -o JustMe.amf
% openjscad name_plate.jscad "--name=Just Me" "--title=Geek" -o JustMe.amf
在使用 OpenJSCAD 建立了一些設計之後,一些通用的函式和部件會變得很有用。include() 函式允許一個 OpenJSCAD 指令碼包含另一個 OpenJSCAD 指令碼。
- https://github.com/BITPlan/docker-openjscad/tree/master/workspace/testinclude
- https://github.com/gilboonet/designs/tree/master/testInclude
// main.jscad
include("lib.jscad");
function main() {
myLib();
return myLib.b(2);
}
以及
// lib.jscad
myLib = function() {
var a = function(n) { // internal
return n*4;
}
myLib.b = function(n) { // public
return sphere(a(n));
}
}
注意:主檔案必須包含呼叫:myLib()
一個遙控器支架的設計,使用了一個名為 “Box” 的類,它從 “Box.jscad” 檔案中包含進來。另請參閱 https://github.com/BITPlan/docker-openjscad/tree/master/workspace/RCHolder ![]()
// title : Remote Control Holder Test
// author : Wolfgang Fahl
// license : Apache License
// revision : 0.0.1
// tags : Cube
// file : RCHolder/main.jscad
include ("Box.jscad");
//
function main() {
BoxFactory();
width = 55;
height = 45;
len = 30;
wall = 1.5;
var boxes = [];
box=BoxFactory.create(width, len, height, wall, false);
boxo= BoxFactory.create(width,len,height,wall,false);
x0=-width*1.5;
y0=-95
box.at(x0, y0, 0);
var ls = [30, 25, 25, 20, 20, 25];
i=0;
x=0;
ls.forEach(function(length) {
box.length=length;
if (++i>3) {
box.x=x0;
box.y=y0+len-wall;
i=0;
}
boxo.x=box.x;
boxo.y=box.y;
boxo.z=box.z;
boxes.push(box.box());
boxes.push(boxo.box());
box.move(width-wall,0,0);
});
return union(boxes);
}
// title : Box Test
// author : Wolfgang Fahl
// license : Apache License
// revision : 0.0.1
// tags : Cube
// file : Box.jscad
class Box {
constructor(width, length, height, wall, center) {
this.width = width;
this.length = length;
this.height = height;
this.wall = wall;
this.center = center;
this.x = 0;
this.y = 0;
this.z = 0;
}
/**
* create a box
*/
box() {
return difference(
cube({
size: [this.width, this.length, this.height],
center: this.center
}),
cube({
size: [this.width - this.wall * 2, this.length - this.wall * 2, this.height - this.wall],
center: this.center
}).translate([this.wall, this.wall, this.wall])
).translate([this.x, this.y, this.z])
}
at(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
move(x, y, z) {
this.at(this.x + x, this.y + y, this.z + z);
}
}
BoxFactory=function () {
BoxFactory.create=function(pWidth, pLength, pHeight, pWall, pCenter) {
return new Box(pWidth,pLength,pHeight,pWall,pCenter);
}
}
參見 柏拉圖立體示例,它使用了遞迴的 include()。不過,這是一個不太好的例子,因為它沒有對函式名進行本地化。一個清晰的寫作風格指南將會展示一個 OpenJSCAD 庫應該是什麼樣子的。
include() 函式支援
- 網路線上遠端(例如 https://openjscad.xyz/):前提是您拖放了檔案,或者它們在網路伺服器上可用(例如示例)
- 網路線上本地(例如 https:///OpenJSCAD/):前提是您拖放了檔案,或者它們在本地網路伺服器上可用
- 網路離線本地(例如 file://..../OpenJSCAD/index.html):前提是您拖放了檔案
- 命令列介面(CLI):前提是它們在本地檔案系統中可用
拖放檔案設定示例

假設您要建立一個大型 OpenJSCAD 專案,您可以使用 include() 來分割功能
ProjectName/
main.jscad # this one contains the "function main()", this file will be <b>executed</b>
addon.jscad # this file could be include("addon.jscad") in main.jscad
optimizer.jscad # '' include("optimizer.jscad") in main.jscad or also in addon.jscad
Makefile # possible Makefile to do the same on CLI
注意:名為 main.jscad 的檔案必須存在,並且必須包含 “function main()” 的宣告。
取決於您的瀏覽器和本地設定,以下內容適用
- Chrome(版本 26)
* Online (http://...): drag & drop entire folder, e.g. ProjectName/ to the drag & drop zone * Offline (file://...): drag & drop all jscad files (but not folder) to the drag & drop zone
- Firefox(版本 19+):將專案的所有 jscad 檔案拖放到拖放區域
- Opera:尚不支援(WebGL 支援尚未可用)
- IE10:尚不支援(WebGL 支援尚未可用)
- 構造實體幾何 (CSG) 庫 是一種建模技術,它使用並集和交集等布林運算來組合 3D 實體。
