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

ドキュメント

正確な B-rep カーネル

正確な境界表現: 解析および NURBS ジオメトリ、ブール演算、フィレット、穴認識、質量特性、検証、テッセレーション、STEP。

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

B-rep カーネルとは

正確なカーネル packages/core/src/cad/brep (24 個のソース ファイル、約 8 660 行、およびテスト) は、ソリッドを正確な境界、つまり正確なエッジのループでトリミングされた解析サーフェスと NURBS サーフェスによって表します。すべてはプレーン データと純粋な関数であるため、B-rep は JSON にシリアル化され、ワーカーの境界を越えて、プロジェクト履歴の差分が変更されません。ブール演算、フィレットと面取り、穴認識、質量特性、検証、防水テッセレーション、STEP 交換はすべて、この 1 つの構造上で機能します。

減算およびフィレット後の正確なプレート ドラッグして周回します · スクロールしてズーム · 右ドラッグしてパンします
A 60 × 40 × 15 box minus a Ø12 cylinder (booleanBrep), then the four vertical edges filleted R4 (blendBrep). Mesh from brepToMesh at chordTol 0.05. 18 vertices, 27 edges, 11 faces; exact volume 34 097.522 mm³.

トポロジテーブル

A Brep インデックステーブルのセットです。エンティティは、オブジェクト参照ではなく、インデックスによって相互に参照します。

実在物ホールドSTEP相手
頂点ポイント、公差VERTEX_POINT
角exact curve, [t0, t1] with t0 < t1, v0 = C(t0), v1 = C(t1), toleranceEDGE_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 アルゴリズム)
正確なプリミティブ、テッセレーション化 ドラッグして周回します · スクロールしてズーム · 右ドラッグしてパンします
makeBox(10,10,10), makeCylinder(5,10), makeCone(5,2,10) and makeSphere(5), each tessellated by brepToMesh at chordTol 0.2 (12, 430, 122 and 1810 triangles) and placed side by side.
トーラス R20 r5 ドラッグして周回します · スクロールしてズーム · 右ドラッグしてパンします
makeTorus(20, 5): 継ぎ目のみで他のエッジのない単一のトロイダル面。chordTol 1 および 30° でテッセレーションされます。正確な体積 2π²Rr² = 9 869.604 mm³ が、massProperties によって返されるものです。

正確なブール値

  1. 交差します。 他のソリッドの面に対する各ソリッドのエッジ (ニュートンによる正確な点)、他のソリッドの表面上にあるエッジ、および一致しない面のすべてのペアの交差曲線は、両方の表面上でリファインされ、線および円として認識され、それ以外の場合はフィット許容差内の 3 次 B スプラインとしてフィットされます。
  2. インプリント。 すべての交点は両方のソリッドの 1 つのレジストリの頂点となり、そこでエッジが分割され、(u, v) ドメインの平面配置を通じて各面がその上の曲線によって切断されます。
  3. 分類します。 各フラグメント内の点は、他のソリッドに対して同じ方向、または反対方向の内側、外側、または上に配置されます。
  4. 縫う。 フラグメントは操作のルールによって保持され、一致するピースが 1 つのエッジになり、同一平面上の隣接するピースがマージされ、結果が検証されます。閉じた多様体ソリッドではない結果がスローされます BooleanError;それは決して返されません。
boolean.ts
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.5399670615134303.539967061515
同じ、エリア8139.2920065876848139.292006587698
同じ、重心(30.000, 20.000, 7.500)(30, 20, 7.5)
球 r10、体積4188.7902047863794188.790204786391
トーラス 20/5、ボリューム9869.604401094759869.604401089358
フィレプレート、ボリューム34097.5222039230234097.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 をフィレットしましたが、拒否されたものはありませんでした。ホールはフェースのみから読み取られます。

acceptHoles — 実際の出力
[{"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 にクランプ)メッシュと正確なサーフェス間の最大距離
angleTolDeg15三角形を横切る最大法線ターン (0 は無効になります)
maxEdge0 (なし)エッジ長ターゲット
maxPointsPerFace200 000安全キャップ
paramStep—massProperties で使用される統合モード

フィレプレート用 defaultChordTol 0.0368 mm が返され、 tessellateBrep 652 個の三角形に加えて、面ごとのメッシュ、エッジ ポリライン、警告が生成されました。

STEP交換

writeStepBreps aP214 (AUTOMOTIVE_DESIGN) ファイルをミリメートルとラジアンで書き込み、部品ごとに 1 つの ADVANCED_BREP_SHAPE_REPRESENTATION を書き込みます。 readStepBreps aP203、AP214、AP242 のジオメトリとトポロジ (変換と製品名を含むアセンブリを含む) を読み取ります。不明なエンティティが報告されています warnings そして彼らの顔は飛び跳ねた。何も推測されません。
writeStepBreps([{ name: "plate", brep }]) — first lines of the real 358-line file
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 レポートの問題構築されたボディのインデックス、方向、または表面上のエッジのエラー問題はエンティティに名前を付けます。何も自動的に修復されません