Documentación
Núcleo B-rep exacto
Representación exacta de límites: geometría analítica y NURBS, booleanos, filetes, reconocimiento de agujeros, propiedades de masa, validación, teselación y STEP.
Traducido automáticamente del inglés. Ver el original en inglés
¿Qué es el núcleo B-rep?
El núcleo exacto en packages/core/src/cad/brep (24 archivos fuente, aproximadamente 8 660 líneas, más pruebas) representa sólidos por su límite exacto: superficies analíticas y NURBS, recortadas por bucles de bordes exactos. Todo son datos simples y funciones puras, por lo que un B-rep se serializa en JSON, cruza el límite de un trabajador y diferencia en el historial del proyecto sin cambios. Booleanos, filetes y chaflanes, reconocimiento de agujeros, propiedades de masa, validación, teselación estanca e intercambio STEP funcionan en esta única estructura.
Tablas de topología
A Brep es un conjunto de tablas de índice. Las entidades se refieren entre sí por índice, nunca por referencia de objeto.
| Entidad | Sostiene | contraparte PASO |
|---|---|---|
| Vértice | punto, tolerancia | VERTEX_POINT |
| Borde | exact curve, [t0, t1] with t0 < t1, v0 = C(t0), v1 = C(t1), tolerance | EDGE_CURVE |
| coedge | un uso de una arista mediante un bucle: índice de arista, invertido, curva p opcional en la cara (u, v) | ORIENTADO_EDGE + PCURVA |
| Bucle | ciclo cerrado de coedges; material a la izquierda visto desde fuera (exterior en sentido horario, agujeros en sentido horario) | EDGE_LOOP |
| Rostro | región de una superficie; invertido significa que la normal exterior es −(S_u × S_v) | ADVANCED_FACE |
| Caparazón | conjunto conectado de caras; una concha cerrada limita un 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"]} Curvas y superficies
Los tipos analíticos utilizan las parametrizaciones STEP (ISO 10303-42), por lo que las caras leídas y escritas en STEP mantienen sus parámetros.
| Tipo | Parametrización |
|---|---|
| línea | C(t) = O + t·d, d unidad, t longitud del arco |
| círculo | C(t) = O + r(cos t·x + sin t·y) |
| elipse | C(t) = O + a cos t·x + b sen t·y |
| avión | S(u,v) = O + u·x + v·y |
| cilindro | S(u,v) = O + r(cos u·x + sin u·y) + v·z |
| cono | S(u,v) = O + (R + v tan α)(cos u·x + sin u·y) + v·z |
| esfera | S(u,v) = O + r cos v(cos u·x + sin u·y) + r sin v·z |
| toro | S(u,v) = O + (R + r cos v)(cos u·x + sin u·y) + r sin v·z |
| revolución | S(u,v) = rotate(C(v), axis, u) |
| extrusión | S(u,v) = C(u) + v·d |
| nurbs | curva o superficie racional B-spline (algoritmos de Piegl & Tiller en nurbs.ts) |
Booleanos exactos
- Intersecarse. Bordes de cada sólido contra las caras del otro (puntos exactos de Newton), bordes que se encuentran en las superficies del otro sólido y las curvas de intersección de cada par de caras no coincidentes, refinadas en ambas superficies y reconocidas como líneas y círculos, de lo contrario ajustadas como B-splines cúbicos dentro de la tolerancia de ajuste.
- Imprimir. Cada punto de intersección se convierte en un vértice en un registro para ambos sólidos, los bordes se dividen allí y cada cara es cortada por las curvas a través de una disposición plana en su dominio (u, v).
- Clasificar. Un punto dentro de cada fragmento se ubica contra el otro sólido: adentro, afuera o adentro con la misma orientación u opuesta.
- Coser. Los fragmentos se mantienen según las reglas de la operación, las piezas coincidentes se convierten en un borde, los vecinos coplanares se fusionan y el resultado se valida. Un resultado que no es un sólido múltiple cerrado arroja
BooleanError; nunca se devuelve.
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 Propiedades de masa
El volumen, el área, el centroide y el tensor de inercia (densidad unitaria, alrededor del centroide, fila principal) provienen del teorema de divergencia sobre las caras límite. Las caras planas se integran exactamente según el teorema de Green a lo largo de las curvas de borde exactas; Las caras curvas se integran en un mosaico de pasos de parámetros de la superficie exacta.
| Cuerpo | massProperties | formulario cerrado |
|---|---|---|
| caja − Ø12 agujero, volumen | 34303.53996706151 | 34303.539967061515 |
| mismo, área | 8139.292006587684 | 8139.292006587698 |
| mismo, centroide | (30.000, 20.000, 7.500) | (30, 20, 7.5) |
| esfera r10, volumen | 4188.790204786379 | 4188.790204786391 |
| toro 20/5, volumen | 9869.60440109475 | 9869.604401089358 |
| plato fileteado, 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.
Filetes, chaflanes y reconocimiento de agujeros
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> En la caja - cuerpo del cilindro había 14 mezclas candidatas; selectBlendEdges(c, { parallel: "z" }) seleccionó los 4 bordes exteriores verticales y blendBrep(b, sel, 4) fileteado todo 4 sin ninguno rechazado en 94 ms. El agujero lee solo de las caras:
[{"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]}]}] Los formularios son simple, counterbore y countersink; los fondos son through, flat y drill-point. El reconocimiento lee rostros, no historial, por lo que una importación STEP, un resultado booleano y una parte paramétrica se reconocen por igual.
Teselado estanco
Cada borde es muestreado una vez en su curva exacta y cada cara que lo utiliza comparte esas muestras, por lo que la malla soldada no tiene grietas. Las caras son trianguladas por Delaunay restringido en su dominio (u, v).
| Opción | Por defecto | Significado |
|---|---|---|
| chordTol | 1/2000 de la diagonal del modelo, sujeta a [0.001, 0.05] mm | distancia máxima entre malla y superficie exacta |
| angleTolDeg | 15 | giro normal máximo a través de un triángulo (0 desactiva) |
| maxEdge | 0 (ninguno) | objetivo de longitud de borde |
| maxPointsPerFace | 200 000 | tapa de seguridad |
| paramStep | — | modo de integración utilizado por MassProperties. |
Para el plato de filete defaultChordTol devolvió 0.0368 mm y tessellateBrep produjo 652 triángulos más mallas por cara, polilíneas de borde y advertencias.
intercambio PASO
writeStepBreps escribe un archivo AP214 (AUTOMOTIVE_DESIGN) en milímetros y radianes, un ADVANCED_BREP_SHAPE_REPRESENTATION por parte. readStepBreps lee la geometría y topología AP203, AP214 y AP242, incluidos los ensamblajes con sus transformaciones y nombres de productos. Se reportan entidades desconocidas en warnings y sus rostros saltaron; no se adivina nada.
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.)); Al volver a leer ese archivo se obtuvo una parte cuyo volumen era 34097.52220392303 mm³, igual al cuerpo escrito con 11 dígitos significativos.
Presupuesto de tiempo
El kernel es sincrónico y se ejecuta en el hilo de la persona que llama. withBudget(ms, f) fija una fecha límite; llamada de bucles largos (pares de caras de un booleano, división de caras, intersección de superficies, teselación) checkBudget, que arroja BudgetExceeded. Los presupuestos anidados mantienen la fecha límite anterior; sin presupuesto un cheque cuesta una comparación.
withBudget(1, () => booleanBrep(makeSphere(10), makeBox(10, 10, 10), "union"))
// BudgetExceeded: the exact model exceeded its time budget of 1 ms Solución de problemas
| Síntoma | Causa | Arreglar |
|---|---|---|
BooleanError | el resultado cosido no es un sólido múltiple cerrado (caras tangentes o casi coincidentes) | mover un operando ligeramente fuera de la tangencia; verifique ambos con validarBrep primero |
BudgetExceeded | la operación tomó más tiempo que su presupuesto | simplificar o darle a la persona que llama un presupuesto mayor |
| RangeError de una primitiva | tamaño no positivo, o toro menor ≥ mayor | p.ej. "El radio menor del toro debe ser menor que el radio mayor" |
mezclar el borde rejected | cara demasiado estrecha para el radio, filo de cuchillo o pared inclinada | radio más pequeño o un chaflán |
| PASO parte faltan caras | entidad no compatible en el archivo | leer warnings de readStepBreps |
| validarBrep informa problemas | error de índice, orientación o borde en superficie en un cuerpo construido. | la emisión nombra la entidad; nada se repara automáticamente |