ドキュメント
正確な B-rep カーネル
正確な境界表現: 解析および NURBS ジオメトリ、ブール演算、フィレット、穴認識、質量特性、検証、テッセレーション、STEP。
英語から自動翻訳されています。 英語の原文を見る
B-rep カーネルとは
正確なカーネル packages/core/src/cad/brep (24 個のソース ファイル、約 8 660 行、およびテスト) は、ソリッドを正確な境界、つまり正確なエッジのループでトリミングされた解析サーフェスと NURBS サーフェスによって表します。すべてはプレーン データと純粋な関数であるため、B-rep は JSON にシリアル化され、ワーカーの境界を越えて、プロジェクト履歴の差分が変更されません。ブール演算、フィレットと面取り、穴認識、質量特性、検証、防水テッセレーション、STEP 交換はすべて、この 1 つの構造上で機能します。
トポロジテーブル
A Brep インデックステーブルのセットです。エンティティは、オブジェクト参照ではなく、インデックスによって相互に参照します。
| 実在物 | ホールド | STEP相手 |
|---|---|---|
| 頂点 | ポイント、公差 | VERTEX_POINT |
| 角 | exact curve, [t0, t1] with t0 < t1, v0 = C(t0), v1 = C(t1), tolerance | EDGE_CURVE |
| コエッジ | ループによるエッジの 1 つの使用法: エッジ インデックス、反転、面内のオプションの P カーブ (u、v) | ORIENTED_EDGE + PCURVE |
| ループ | 共通エッジの閉じたサイクル。外側から見た左側の素材(外側CCW、穴CW) | EDGE_LOOP |
| 顔 | 1つの表面の領域。 reversed means the outward normal is −(S_u × S_v) | ADVANCED_FACE |
| シェル | 接続された面のセット。閉じたシェルがボリュームを境界付ける | CLOSED_SHELL |
Seams (an edge used twice by the same face, such as the generator line of a full cylinder) and poles (a loop through a degenerate point, such as a cone apex) need no special entities. That is why the exact sphere has 2 vertices, 1 edge and 1 face, and the torus 1 vertex, 2 edges and 1 face.
makeBox(60, 40, 15) {"V":8,"E":12,"F":6,"S":1,"surfaces":["plane"]}
makeSphere(10) {"V":2,"E":1,"F":1,"S":1,"surfaces":["sphere"]}
makeTorus(20, 5) {"V":1,"E":2,"F":1,"S":1,"surfaces":["torus"]}
makeCone(10, 4, 20) {"V":2,"E":3,"F":3,"S":1,"surfaces":["cone","plane"]} 曲線と曲面
分析タイプは STEP (ISO 10303-42) パラメータ化を使用するため、STEP から読み取られる面と STEP に書き込まれる面はパラメータを保持します。
| タイプ | パラメータ化 |
|---|---|
| ライン | C(t) = O + t・d、d単位、t弧長 |
| 丸 | C(t) = O + r(cos t·x + sin t·y) |
| 楕円 | C(t) = O + a cos t・x + b sin t・y |
| 飛行機 | S(u,v) = O + u·x + v·y |
| シリンダー | S(u,v) = O + r(cos u·x + sin u·y) + v·z |
| 円錐 | S(u,v) = O + (R + v tan α)(cos u·x + sin u·y) + v·z |
| 球 | S(u,v) = O + r cos v(cos u·x + sin u·y) + r sin v·z |
| トーラス | S(u,v) = O + (R + r cos v)(cos u·x + sin u·y) + r sin v·z |
| 回転 | S(u,v) = rotate(C(v), axis, u) |
| 押し出し | S(u,v) = C(u) + v·d |
| ナーブス | 有理 B スプライン曲線または曲面 (nurbs.ts の Piegl & Tiller アルゴリズム) |
正確なブール値
- 交差します。 他のソリッドの面に対する各ソリッドのエッジ (ニュートンによる正確な点)、他のソリッドの表面上にあるエッジ、および一致しない面のすべてのペアの交差曲線は、両方の表面上でリファインされ、線および円として認識され、それ以外の場合はフィット許容差内の 3 次 B スプラインとしてフィットされます。
- インプリント。 すべての交点は両方のソリッドの 1 つのレジストリの頂点となり、そこでエッジが分割され、(u, v) ドメインの平面配置を通じて各面がその上の曲線によって切断されます。
- 分類します。 各フラグメント内の点は、他のソリッドに対して同じ方向、または反対方向の内側、外側、または上に配置されます。
- 縫う。 フラグメントは操作のルールによって保持され、一致するピースが 1 つのエッジになり、同一平面上の隣接するピースがマージされ、結果が検証されます。閉じた多様体ソリッドではない結果がスローされます
BooleanError;それは決して返されません。
export const booleanBrep: (A: Brep, B: Brep, op: BooleanOp, options?: BooleanOptions) => BooleanResult
export interface BooleanOptions {
tol?: number // coincidence, default 1e-8 × model size, at least 1e-7 mm
fitTol?: number // fitted intersection curves, default 1e-6 × size, at least 1e-6 mm
seedAngleDeg?: number // normal turn per seed-mesh triangle, default 10
debug?: (stage: string, data: unknown) => void
}
export interface BooleanResult {
brep: Brep; warnings: string[]
stats: { intersectionCurves: number; splitPoints: number; fragments: number; keptFaces: number }
} import { brep } from "@cadcamfun/core"
const { makeBox, makeCylinder, frame, booleanBrep, validateBrep, massProperties } = brep
const box = makeBox(60, 40, 15)
const hole = makeCylinder(6, 25, frame({ x: 30, y: 20, z: -5 }))
const r = booleanBrep(box, hole, "subtract") // 141 ms
r.stats // {"intersectionCurves":2,"splitPoints":12,"fragments":13,"keptFaces":7}
r.warnings // []
validateBrep(r.brep)
// {"valid":true,"manifoldSolid":true,"genus":1,"volume":34303.53996706151,"issues":[]}
massProperties(r.brep).volume // 34303.53996706151 = 60·40·15 − π·6²·15 exactly 質量特性
体積、面積、重心、および慣性テンソル (単位密度、重心付近、行優先) は、境界面に関する発散定理から得られます。平面は、グリーンの定理によって正確なエッジ曲線に沿って正確に統合されます。曲面は、正確なサーフェスのパラメータ ステップ テッセレーション上に統合されます。
| 体 | massProperties | クローズドフォーム |
|---|---|---|
| ボックス − Ø12 穴、体積 | 34303.53996706151 | 34303.539967061515 |
| 同じ、エリア | 8139.292006587684 | 8139.292006587698 |
| 同じ、重心 | (30.000, 20.000, 7.500) | (30, 20, 7.5) |
| 球 r10、体積 | 4188.790204786379 | 4188.790204786391 |
| トーラス 20/5、ボリューム | 9869.60440109475 | 9869.604401089358 |
| フィレプレート、ボリューム | 34097.52220392302 | 34097.522203923065 |
The filleted-plate closed form is the subtracted plate minus four corner slivers of (r² − πr²/4)·h = (16 − 4π)·15 each.
フィレット、面取り、穴の認識
export const blendCandidates: (b: Brep, minAngleDegrees?: number /* 0.5 */) => BlendCandidate[]
export const selectBlendEdges: (edges: ReadonlyArray<BlendCandidate>, s?: BlendSelector) => BlendCandidate[]
// BlendSelector: parallel?: "x"|"y"|"z", within?: box, kind?: "convex"|"concave"|"both" (default convex), minLength?, curved?
export const blendBrep: (b: Brep, edges: ReadonlyArray<BlendCandidate>, size: number,
style?: "fillet" | "chamfer", options?: BlendOptions) => BlendResult
// BlendResult: brep, blended, vertices (rolling-ball corners), rejected (edge ids), ...
export const recognizeHoles: (b: Brep, options?: HoleRecognitionOptions) => ReadonlyArray<RecognizedHole> ボックスのシリンダー本体には、14 個のブレンド候補がありました。 selectBlendEdges(c, { parallel: "z" }) 4 の垂直外側エッジを選択し、 blendBrep(b, sel, 4) 4 ミリ秒以内にすべての 94 をフィレットしましたが、拒否されたものはありませんでした。ホールはフェースのみから読み取られます。
[{"entry":{"x":30,"y":20,"z":15},"direction":{"x":0,"y":0,"z":-1},"depth":15,"diameter":12,
"form":"simple","bottom":"through",
"segments":[{"kind":"cylinder","start":0,"end":15,"diameterStart":12,"diameterEnd":12,"faces":[6]}]}] フォームは simple, counterbore そして countersink;ボトムスは through, flat そして drill-point。認識では履歴ではなく面が読み取られるため、STEP インポート、ブール結果、およびパラメトリック パーツは同様に認識されます。
防水テッセレーション
すべてのエッジはその正確な曲線上で 1 回サンプリングされ、それを使用するすべての面でそれらのサンプルが共有されるため、溶接されたメッシュには亀裂がありません。面は、(u, v) ドメインで制約された Delaunay によって三角形化されます。
| オプション | デフォルト | 意味 |
|---|---|---|
| chordTol | モデル対角線の 1/2000、[0.001, 0.05] mm にクランプ) | メッシュと正確なサーフェス間の最大距離 |
| angleTolDeg | 15 | 三角形を横切る最大法線ターン (0 は無効になります) |
| maxEdge | 0 (なし) | エッジ長ターゲット |
| maxPointsPerFace | 200 000 | 安全キャップ |
| paramStep | — | massProperties で使用される統合モード |
フィレプレート用 defaultChordTol 0.0368 mm が返され、 tessellateBrep 652 個の三角形に加えて、面ごとのメッシュ、エッジ ポリライン、警告が生成されました。
STEP交換
writeStepBreps aP214 (AUTOMOTIVE_DESIGN) ファイルをミリメートルとラジアンで書き込み、部品ごとに 1 つの ADVANCED_BREP_SHAPE_REPRESENTATION を書き込みます。 readStepBreps aP203、AP214、AP242 のジオメトリとトポロジ (変換と製品名を含むアセンブリを含む) を読み取ります。不明なエンティティが報告されています warnings そして彼らの顔は飛び跳ねた。何も推測されません。
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('CADCAMFUN exact B-rep'),'2;1');
FILE_NAME('plate','2026-10-15T04:49:21',(''),(''),'CADCAMFUN B-rep kernel','CADCAMFUN','');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
ENDSEC;
DATA;
#1=APPLICATION_CONTEXT('core data for automotive mechanical design processes');
#2=APPLICATION_PROTOCOL_DEFINITION('international standard','automotive_design',2000,#1);
#3=PRODUCT_CONTEXT('',#1,'mechanical');
#4=PRODUCT_DEFINITION_CONTEXT('part definition',#1,'design');
#5=(LENGTH_UNIT()NAMED_UNIT(*)SI_UNIT(.MILLI.,.METRE.)); そのファイルを読み戻すと、体積が 34097.52220392303 mm³ で、有効桁数が 11 桁に書き込まれた本体に等しい 1 つの部分が得られました。
時間の予算
カーネルは同期しており、呼び出し元のスレッドで実行されます。 withBudget(ms, f) 期限を設定する。長いループ (ブール値の面のペア、面の分割、面の交差、テッセレーション) 呼び出し checkBudget、投げます BudgetExceeded。ネストされた予算では、より早い期限が維持されます。予算がなければ、小切手には比較 1 回の費用がかかります。
withBudget(1, () => booleanBrep(makeSphere(10), makeBox(10, 10, 10), "union"))
// BudgetExceeded: the exact model exceeded its time budget of 1 ms トラブルシューティング
| 症状 | 原因 | 修理 |
|---|---|---|
BooleanError | 縫い合わせた結果は閉じた多様体ソリッドではありません (接線面またはほぼ一致する面) | オペランドを接線からわずかに外して移動します。最初に validateBrep で両方を確認してください |
BudgetExceeded | 作戦は予算よりも時間がかかった | 簡素化するか、発信者に大きな予算を与える |
| プリミティブからの RangeError | 非正のサイズ、または小トーラス ≥ 大トーラス | 例えば「トーラスの副半径は主半径より小さくなければなりません」 |
エッジをブレンドする rejected | 半径、ナイフエッジ、または傾斜した壁に対して面が狭すぎる | 半径が小さい、または面取り |
| STEP パーツの面がありません | ファイル内のサポートされていないエンティティ | 読む warnings readStepBreps から |
| validateBrep レポートの問題 | 構築されたボディのインデックス、方向、または表面上のエッジのエラー | 問題はエンティティに名前を付けます。何も自動的に修復されません |