Dokumentation
Exakter B-Rep-Kernel
Exakte Grenzdarstellung: analytische und NURBS-Geometrie, Boolesche Werte, Verrundungen, Locherkennung, Masseneigenschaften, Validierung, Tessellation und STEP.
Automatisch aus dem Englischen übersetzt. Englisches Original ansehen
Was der B-Rep-Kernel ist
Der genaue Kernel in packages/core/src/cad/brep (24 Quelldateien, etwa 8 660 Zeilen, plus Tests) stellt Körper anhand ihrer genauen Grenze dar: analytische und NURBS-Oberflächen, getrimmt durch Schleifen exakter Kanten. Alles besteht aus einfachen Daten und reinen Funktionen, daher wird ein B-Rep in JSON serialisiert, überschreitet eine Worker-Grenze und ändert sich unverändert im Projektverlauf. Boolesche Werte, Verrundungen und Fasen, Locherkennung, Masseneigenschaften, Validierung, wasserdichte Tessellation und STEP-Austausch funktionieren alle auf dieser einen Struktur.
Topologietabellen
A Brep ist eine Reihe von Indextabellen. Entitäten verweisen aufeinander über einen Index, niemals über einen Objektverweis.
| Juristische Person | Hält | STEP-Gegenstück |
|---|---|---|
| Scheitel | punkt, Toleranz | VERTEX_POINT |
| Rand | exact curve, [t0, t1] with t0 < t1, v0 = C(t0), v1 = C(t1), tolerance | EDGE_CURVE |
| Coedge | eine Verwendung einer Kante durch eine Schleife: Kantenindex, umgekehrt, optionale p-Kurve in der Fläche (u, v) | ORIENTED_EDGE + PCURVE |
| Schleife | geschlossener Kreislauf von Kanten; Material links von außen gesehen (äußere CCW, Löcher CW) | EDGE_LOOP |
| Gesicht | bereich einer Oberfläche; umgekehrt bedeutet, dass die äußere Normale −(S_u × S_v) ist. | ADVANCED_FACE |
| Hülse | verbundener Satz von Gesichtern; Eine geschlossene Hülle begrenzt ein Volumen | 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"]} Kurven und Flächen
Analysetypen verwenden die STEP-Parametrisierung (ISO 10303-42), sodass aus STEP gelesene und in STEP geschriebene Gesichter ihre Parameter behalten.
| Typ | Parametrierung |
|---|---|
| linie | C(t) = O + t·d, d-Einheit, t Bogenlänge |
| kreis | C(t) = O + r(cos t·x + sin t·y) |
| ellipse | C(t) = O + a cos t·x + b sin t·y |
| flugzeug | S(u,v) = O + u·x + v·y |
| zylinder | S(u,v) = O + r(cos u·x + sin u·y) + v·z |
| kegel | S(u,v) = O + (R + v tan α)(cos u·x + sin u·y) + v·z |
| kugel | S(u,v) = O + r cos v(cos u·x + sin u·y) + r sin v·z |
| torus | S(u,v) = O + (R + r cos v)(cos u·x + sin u·y) + r sin v·z |
| revolution | S(u,v) = rotate(C(v), axis, u) |
| extrusion | S(u,v) = C(u) + v·d |
| nurbs | rationale B-Spline-Kurve oder -Oberfläche (Piegl & Tiller-Algorithmen in nurbs.ts) |
Exakte Boolesche Werte
- Schneiden. Kanten jedes Volumenkörpers gegenüber den Flächen des anderen (genaue Punkte nach Newton), Kanten, die auf den Oberflächen des anderen Volumenkörpers liegen, und die Schnittkurven jedes Paares nicht zusammenfallender Flächen, verfeinert auf beiden Oberflächen und erkannt als Linien und Kreise, ansonsten innerhalb der Anpassungstoleranz als kubische B-Splines angepasst.
- Impressum. Jeder Schnittpunkt wird zu einem Scheitelpunkt in einem Register für beide Körper, Kanten werden dort geteilt und jede Fläche wird durch die darauf befindlichen Kurven durch eine planare Anordnung in ihrem (u, v)-Bereich geschnitten.
- Klassifizieren. Ein Punkt innerhalb jedes Fragments liegt gegenüber dem anderen Festkörper: innen, außen oder auf derselben oder entgegengesetzten Ausrichtung.
- Nähen. Fragmente werden durch die Regeln der Operation beibehalten, zusammenfallende Teile werden zu einer Kante, koplanare Nachbarn verschmelzen und das Ergebnis wird validiert. Ein Ergebnis, das kein geschlossener Mannigfaltigkeitskörper ist
BooleanError; es wird nie zurückgegeben.
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 Masseneigenschaften
Volumen, Fläche, Schwerpunkt und der Trägheitstensor (Einheitsdichte, um den Schwerpunkt, Hauptreihe) ergeben sich aus dem Divergenzsatz über die Grenzflächen. Planare Flächen werden nach dem Satz von Green entlang der exakten Kantenkurven exakt integriert; Gekrümmte Flächen werden auf einer Parameterschritt-Tessellation der exakten Oberfläche integriert.
| Körper | massProperties | Geschlossenes Formular |
|---|---|---|
| box − Ø12 Loch, Volumen | 34303.53996706151 | 34303.539967061515 |
| gleich, Bereich | 8139.292006587684 | 8139.292006587698 |
| gleich, Schwerpunkt | (30.000, 20.000, 7.500) | (30, 20, 7.5) |
| kugel r10, Volumen | 4188.790204786379 | 4188.790204786391 |
| torus 20/5, Volumen | 9869.60440109475 | 9869.604401089358 |
| filetierter Teller, Volumen | 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.
Erkennung von Verrundungen, Fasen und Löchern
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> Auf dem Kasten-Zylinder-Körper befanden sich 14 Mischungskandidaten; selectBlendEdges(c, { parallel: "z" }) wählte die 4 vertikalen Außenkanten aus und blendBrep(b, sel, 4) alle 4 wurden in 94 ms filetiert und keiner wurde abgelehnt. Das Loch las allein aus den Gesichtern zurück:
[{"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]}]}] Formen sind simple, counterbore und countersink; böden sind through, flat und drill-point. Die Erkennung liest Gesichter, nicht den Verlauf, sodass ein STEP-Import, ein boolesches Ergebnis und ein parametrischer Teil gleichermaßen erkannt werden.
Wasserdichte Tessellation
Jede Kante wird einmal auf ihrer exakten Kurve abgetastet und jede Fläche, die sie verwendet, teilt diese Proben, sodass das geschweißte Netz keine Risse aufweist. Gesichter werden durch eingeschränktes Delaunay in ihrem (u, v)-Bereich trianguliert.
| Option | Standard | Bedeutung |
|---|---|---|
| chordTol | 1/2000 der Modelldiagonale, eingespannt auf [0.001, 0.05] mm | maximaler Abstand zwischen Netz und exakter Oberfläche |
| angleTolDeg | 15 | maximale normale Drehung über ein Dreieck (0 deaktiviert) |
| maxEdge | 0 (keine) | kantenlängenziel |
| maxPointsPerFace | 200 000 | sicherheitskappe |
| paramStep | — | von massProperties verwendeter Integrationsmodus |
Für den filetierten Teller defaultChordTol gab 0.0368 mm zurück und tessellateBrep erzeugte 652 Dreiecke plus Flächennetze, Kantenpolylinien und Warnungen.
STEP-Austausch
writeStepBreps schreibt eine AP214 (AUTOMOTIVE_DESIGN)-Datei in Millimetern und Bogenmaß, eine ADVANCED_BREP_SHAPE_REPRESENTATION pro Teil. readStepBreps liest die Geometrie und Topologie von AP203, AP214 und AP242, einschließlich Baugruppen mit ihren Transformationen und Produktnamen. Unbekannte Entitäten werden in gemeldet warnings und ihre Gesichter hüpften; nichts wird erraten.
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.)); Das Zurücklesen dieser Datei ergab einen Teil mit einem Volumen von 34097,52220392303 mm³, was dem geschriebenen Text mit 11 signifikanten Ziffern entspricht.
Zeitbudget
Der Kernel ist synchron und läuft im Thread des Aufrufers. withBudget(ms, f) legt eine Frist fest; Aufruf von langen Schleifen (Flächenpaare eines Booleschen Werts, Flächenaufteilung, Flächenschnittpunkt, Tessellation). checkBudget, was wirft BudgetExceeded. Bei verschachtelten Budgets bleibt die frühere Frist erhalten; Ohne Budget kostet ein Scheck einen Vergleich.
withBudget(1, () => booleanBrep(makeSphere(10), makeBox(10, 10, 10), "union"))
// BudgetExceeded: the exact model exceeded its time budget of 1 ms Fehlerbehebung
| Symptom | Ursache | Fix |
|---|---|---|
BooleanError | das genähte Ergebnis ist kein geschlossener Mannigfaltigkeitskörper (tangentiale oder nahezu zusammenfallende Flächen). | einen Operanden leicht von der Tangentialität verschieben; Überprüfen Sie beide zuerst mit validateBrep |
BudgetExceeded | die Operation dauerte länger als vorgesehen | vereinfachen oder dem Anrufer ein größeres Budget zur Verfügung stellen |
| RangeError von einem Grundelement | nicht positive Größe oder kleinerer Torus ≥ großer | z.B. „Der kleinere Radius des Torus muss kleiner sein als der große Radius.“ |
rand einblenden rejected | fläche zu schmal für Radius, Messerkante oder schräge Wand | kleinerer Radius oder eine Fase |
| Im STEP-Teil fehlen Flächen | nicht unterstützte Entität in der Datei | lesen warnings von readStepBreps |
| validateBrep meldet Probleme | index-, Orientierungs- oder Kante-auf-Oberfläche-Fehler in einem gebauten Körper | das Problem benennt die Entität; nichts wird automatisch repariert |