コンテンツへスキップ
CADCAMFUN
ドキュメント

ドキュメント

メッシュとCSGカーネル

パラメトリック ソリッドからの閉じた三角形メッシュ、凸状の高速パスを備えた BSP ブール値、クリーンアップおよびトポロジ チェック。

英語から自動翻訳されています。 英語の原文を見る

メッシュカーネルとは

メッシュ カーネルは閉じた三角形メッシュ上で動作します。パラメトリック プリミティブからメッシュを構築します (meshOf)、それらを測定します(meshVolume, meshBounds, meshTopology)、それらをブール値と組み合わせます (booleanMesh, booleanAll)。これは、ビューポートが表示するもの、CAM ジェネレーター マシンが表示するもの、STL エクスポートが書き込むものです。

これは正確な境界表現ではありません。切断された円柱はファセットされた円柱のままであり、フィレットや測定を行う面トポロジはありません。正確な面、フィレット、質量特性、STEP については、 B-repカーネル は別のコードです。

ファイルライン役割
cad/solid.ts659ソリッド スキーマ (ボックス、シリンダー、球、円錐、トーラス、押し出し、回転)、meshOf、meshVolume、meshBounds
cad/csg.ts459BSP ブール値、凸型分類器、変換/回転/マージ
cad/mesh-clean.ts626溶接、T ジャンクションの修復、共面マージ、再三角形分割
cad/mesh-topology.ts110多様体、貝殻、属、体積、面積
cad/triangulate.ts383穴のある多角形の三角形分割
穴あきボス付き穴あきプレート ドラッグして周回します · スクロールしてズーム · 右ドラッグしてパンします
実数の booleanMesh 出力: 60 × 40 × 10 ボックスから 4 つの Ø6 穴 (booleanAll 減算) を差し引き、Ø20 × 8 ボスと結合し、Ø10 を貫通させます。 640 三角形。メッシュトポロジーは、閉じた固体、1 シェル、属数 5、V 23981.4 mm³ を報告します。

メッシュタイプとプリミティブ

solid.ts
export interface Mesh {
  readonly positions: Float32Array   // x, y, z per vertex
  readonly indices: Uint32Array      // three per triangle, counter-clockwise seen from outside
}
export const meshOf: (solid: Solid, tolerance?: number /* 0.1 mm */) => Mesh
export const meshVolume: (mesh: Mesh) => number     // signed; positive when outward-facing
export const meshBounds: (mesh: Mesh) => SolidBounds
固体フィールド限界
箱原点、サイズ {x, y, z}サイズ > 0
シリンダー原点、半径、高さ、セグメント、軸?セグメント 3 ~ 512; z軸 | × | y
球中心、半径、リングリング 2 – 256
円錐原点、baseRadius、topRadius、高さ、セグメント、軸?トップ半径 ≥ 0;セグメント 3 ~ 512
トーラス中心、majorRadius、minorRadius、回転?、majorSegments、minorSegments、軸?3-512 および 3-256
押し出すプロファイル (≥ 3 ポイント、閉じていない)、高さ、原点?xYのプロファイル
回転するプロファイル (XZ 内の ≥ 2 点)、角度、セグメント?zについて。セグメント 3 ~ 512、デフォルト 16
segments そして rings 最小値は次のとおりです。 meshOf コードエラーが範囲内に収まるまでそれらを上げます tolerance, using step = 4·asin(√(min(1, tol/r)/2)). Two budgets stop runaway tolerances.
ガード価値エラーメッセージ
許容誤差は正で有限である必要があります—メッシュ許容値は正で有限でなければなりません
曲線ごとのセグメント数65 536メッシュ許容値がサブディビジョンの予算を超えています
グリッドの行×列(球、トーラス、回転)1 000 000メッシュ許容値が頂点バジェットを超えています

Ø6 シリンダー segments: 24 許容値 0.05 では、96 個の三角形 (24 個の辺、2 つの 24 角のキャップ) が得られました。 Ø20 は 128 です。これは、より大きな半径では 32.0 mm 以内に収まるために 05 個のセグメントが必要だったためです。

バイナリ空間分割によるブール値

各オペランドは分類子になります。一般的なメッシュは BSP ツリーを取得します。凸面メッシュ (閉じていて接続されており、すべてのエッジが凸面) は、その別個の面にすぎないため、ボックスは 6 つの平面であり、1 万個の三角形からなる球は、凸面固体の BSP が縮退する二次連鎖を構築することなく分類されます。ポリゴンはリストとして分類され、他のオペランドの境界ボックスから離れたポリゴンは、何も歩かずに保持または削除されます。

  1. If either mesh is empty, or the bounding boxes do not meet (within tolerance), answer directly: union = merge, subtract = a, intersect = empty.
  2. A と B の分類器 (凸面または BSP) を構築します。
  3. ユニオン: A を B の外側に、B を A の外側に保ち、B の面を A が同じ方向を向いているのと一致するようにドロップします。そのため、共有された面が一度保持されます。
  4. Subtract and intersect follow the classic a.clipTo(b), b.clipTo(a), b.invert() sequence on polygon lists, without copying trees.
  5. ポリゴン スープをクリーンアップします。max(10・eps, 1e-9・size) 以内のポイントを溶接し、T 字路を閉じ、スライバー間の最大 1e-4・size のギャップを閉じ、同一平面上のフラグメントをマージして再三角形化します。
csg.ts
export type BooleanOp = "union" | "subtract" | "intersect"
export interface CsgOptions {
  /** Distance below which a point counts as on a plane, mm. Default 1e-7 × the larger extent. */
  readonly tolerance?: number
  /** Merge coplanar fragments and re-triangulate (default true). */
  readonly mergeCoplanar?: boolean
}
export const booleanMesh: (a: Mesh, b: Mesh, op: BooleanOp, options?: CsgOptions) => Mesh
/** Union reduced as a balanced tree; subtract and intersect fold left to right. */
export const booleanAll: (meshes: ReadonlyArray<Mesh>, op: BooleanOp, options?: CsgOptions) => Mesh
export const translateMesh: (mesh: Mesh, dx: number, dy: number, dz: number) => Mesh
export const rotateMesh: (mesh: Mesh, axis: V3, radians: number, origin?: V3) => Mesh
export const mergeMeshes: (meshes: ReadonlyArray<Mesh>) => Mesh

三角形の数は、ブール値の数ではなく、フィーチャとともに増加します。マージ ステップでは、同一平面上のスライバーが面全体に戻されます。上のプレートでは、箱には 12 個の三角形があり、4 つの穴の後に 412、ボスの後に 540、穴の後に 640 がありました。チェーン全体は 96 ミリ秒で実行されました。

曲線入力での結合、減算、交差

A 20 mm cube at the origin against a sphere of radius 12 centred on its far corner (20, 20, 20), meshed at tolerance 0.2 (624 triangles). Real volumes:

結果体積、mm3三角形
球体だけ7 063.84 (正確な 7 238.23)624
立方体∩球882.98112
立方体∪球14 180.86—
立方体 - 球7 117.02—

チェック: 8 000 + 7 063.84 − 882.98 = 14 180.86 および 8 000 − 882.98 = 7 117.02 であるため、3 つの結果は互いに一致しています。百番目まで。球メッシュ自体は、正確な球よりも 2.4 % 下にあります。これは、ブール誤差ではなく、粗い許容値のファセットです。

立方体 - 球 ドラッグして周回します · スクロールしてズーム · 右ドラッグしてパンします
減算の結果: 角から 8 番目の球体がえぐられた立方体。
立方体∩球 ドラッグして周回します · スクロールしてズーム · 右ドラッグしてパンします
交差結果: 立方体の内側にある球の 8 番目。

トポロジチェック

meshTopology 頂点、辺、三角形を数え、境界、非多様体および方向が間違っている辺を見つけ、三角形と殻を縮退させ、オイラー特性と属数を導き出します。 describeTopology アシスタントとビューポートが使用する 1 行の概要を出力します。
meshTopology(bored) — 実際の出力
{"vertices":312,"triangles":640,"edges":960,"boundaryEdges":0,"nonManifoldEdges":0,
 "misorientedEdges":0,"degenerateTriangles":0,"shells":1,"eulerCharacteristic":-8,"genus":5,
 "closed":true,"solid":true,"volume":23981.43509870267,"area":8238.640705862534}
// describeTopology → "closed solid, 1 shell, genus 5, 640 triangles, V 23981.4 mm³, A 8238.6 mm²"

V − E + F = 312 − 960 + 640 = −8 = 2 − 2g, so g = 5: the four drilled holes plus the bore, which runs through the boss and the plate.

ポリゴンの三角形分割

triangulatePolygon(outer, holes) インデックス トリプルを外側のリングと穴の連結に返します。 4 × 4 の正方形に 2 × 2 の穴があると、8 つの三角形が得られます。
実際の出力
triangulatePolygon(
  [{x:0,y:0},{x:4,y:0},{x:4,y:4},{x:0,y:4}],
  [[{x:1,y:1},{x:1,y:3},{x:3,y:3},{x:3,y:1}]])
// [[0,4,5],[7,4,0],[3,0,5],[7,0,1],[2,3,5],[6,7,1],[2,5,6],[6,1,2]]
triangulatePolygonChecked 返品 undefined 入力を三角測量できない場合 (自己交差リング、外側リングの外側の穴) の部分的な結果の代わりに。

トラブルシューティング

症状原因修理
ブール値の結果に穴または反転した面があります入力が開いているか、時計回りに巻かれています両方の入力を MeshTopology で確認してください:boundaryEdges と missorientedEdges は 0 である必要があります
両方のオペランドに共有される面が欠落しているか、二重になっています面はほぼ一致していますが、正確には一致していません (許容値よりも離れています)オペランドを同じ平面にスナップするか、CsgOptions.tolerance を上げます
RangeError: メッシュ許容値がサブディビジョンの予算を超えています半径に対して公差が小さすぎます公差プリセットを使用します (0.1 ~ 0.0005 mm)
体積は式と異なります粗い公差でのファセット加工メッシュをより細かくするか、正確な質量特性を得るには B-rep カーネルを使用します
多くのツールでブール演算が遅い最初に構築されたツールの結合ツールを 1 つずつ減算します (booleanAll はこれを実行します): 各凸ツールは少数の平面です