Documentação
Kernel B-rep exato
Representação exata de limites: geometria analítica e NURBS, booleanos, filetes, reconhecimento de furos, propriedades de massa, validação, mosaico e STEP.
Traduzido automaticamente do inglês. Ver o original em inglês
O que é o kernel B-rep
O kernel exato em packages/core/src/cad/brep (24 arquivos de origem, cerca de 8 660 linhas, mais testes) representa sólidos por seu limite exato: superfícies analíticas e NURBS, aparadas por loops de arestas exatas. Tudo são dados simples e funções puras, portanto, um representante B serializa para JSON, cruza o limite do trabalhador e difere no histórico do projeto inalterado. Booleanos, filetes e chanfros, reconhecimento de furos, propriedades de massa, validação, mosaico estanque e troca STEP, todos funcionam nesta estrutura.
Tabelas de topologia
A Brep é um conjunto de tabelas de índice. As entidades referem-se umas às outras por índice, nunca por referência de objeto.
| Entidade | Detém | Contraparte STEP |
|---|---|---|
| Vértice | ponto, tolerância | VERTEX_POINT |
| Borda | exact curve, [t0, t1] with t0 < t1, v0 = C(t0), v1 = C(t1), tolerance | EDGE_CURVE |
| Coedge | um uso de uma aresta por um loop: índice de aresta, invertido, curva p opcional na face (u, v) | ORIENTED_EDGE + PCURVE |
| Laço | ciclo fechado de coedes; material à esquerda visto de fora (externo no sentido anti-horário, furos no sentido horário) | EDGE_LOOP |
| Face | região de uma superfície; invertido significa que o normal externo é −(S_u × S_v) | ADVANCED_FACE |
| Concha | conjunto conectado de faces; uma concha fechada limita um volume | 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 e superfícies
Os tipos analíticos usam as parametrizações STEP (ISO 10303-42), portanto, as faces lidas e gravadas em STEP mantêm seus parâmetros.
| Tipo | Parametrização |
|---|---|
| linha | C(t) = O + t·d, unidade d, comprimento do arco t |
| 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ão | S(u,v) = O + u·x + v·y |
| cilindro | S(u,v) = O + r(cos u·x + sin u·y) + v·z |
| cone | 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 |
| revolução | S(u,v) = rotate(C(v), axis, u) |
| extrusão | S(u,v) = C(u) + v·d |
| incomoda | curva ou superfície B-spline racional (algoritmos Piegl & Tiller em nurbs.ts) |
Booleanos exatos
- Cruzar. Arestas de cada sólido contra as faces do outro (pontos exatos de Newton), arestas situadas nas superfícies do outro sólido e as curvas de interseção de cada par de faces não coincidentes, refinadas em ambas as superfícies e reconhecidas como linhas e círculos, caso contrário ajustadas como splines B cúbicas dentro da tolerância de ajuste.
- Imprimir. Cada ponto de intersecção torna-se um vértice em um registro para ambos os sólidos, as arestas são divididas ali e cada face é cortada pelas curvas nela através de um arranjo planar em seu domínio (u, v).
- Classificar. Um ponto dentro de cada fragmento está localizado contra o outro sólido: dentro, fora ou sobre com orientação igual ou oposta.
- Costurar. Os fragmentos são mantidos pelas regras da operação, as peças coincidentes tornam-se uma aresta, os vizinhos coplanares se fundem e o resultado é validado. Um resultado que não é uma variedade fechada gera
BooleanError; nunca é devolvido.
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 Propriedades de massa
Volume, área, centróide e o tensor de inércia (densidade unitária, sobre o centróide, linha maior) vêm do teorema da divergência sobre as faces limite. As faces planas são integradas exatamente pelo teorema de Green ao longo das curvas exatas das arestas; faces curvas são integradas em um mosaico de etapas de parâmetro da superfície exata.
| Corpo | massProperties | Formulário fechado |
|---|---|---|
| caixa − Ø12 furo, volume | 34303.53996706151 | 34303.539967061515 |
| mesmo, área | 8139.292006587684 | 8139.292006587698 |
| mesmo, centróide | (30.000, 20.000, 7.500) | (30, 20, 7.5) |
| esfera r10, volume | 4188.790204786379 | 4188.790204786391 |
| toro 20/5, volume | 9869.60440109475 | 9869.604401089358 |
| prato filetado, volume | 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, chanfros e reconhecimento de furos
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> Na caixa - corpo do cilindro havia 14 candidatos à mistura; selectBlendEdges(c, { parallel: "z" }) escolheu as 4 bordas externas verticais e blendBrep(b, sel, 4) filetou todos 4 sem nenhum rejeitado em 94 ms. O buraco era lido apenas pelos rostos:
[{"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]}]}] Os formulários são simple, counterbore e countersink; fundos são through, flat e drill-point. O reconhecimento lê rostos, não histórico, portanto, uma importação STEP, um resultado booleano e uma parte paramétrica são reconhecidos da mesma forma.
Tesselação estanque
Cada aresta é amostrada uma vez em sua curva exata e cada face que a utiliza compartilha essas amostras, de modo que a malha soldada não apresenta rachaduras. As faces são trianguladas por Delaunay restrito em seu domínio (u, v).
| Opção | Padrão | Significado |
|---|---|---|
| chordTol | 1/2000 da diagonal do modelo, fixada em [0.001, 0.05] mm | distância máxima entre a malha e a superfície exata |
| angleTolDeg | 15 | giro normal máximo em um triângulo (0 desativa) |
| maxEdge | 0 (nenhum) | alvo de comprimento de borda |
| maxPointsPerFace | 200 000 | tampa de segurança |
| paramStep | — | modo de integração usado por massProperties |
Para o prato de filé defaultChordTol retornou 0.0368 mm e tessellateBrep produziu 652 triângulos mais malhas por face, polilinhas de borda e avisos.
Troca de ETAPA
writeStepBreps grava um arquivo AP214 (AUTOMOTIVE_DESIGN) em milímetros e radianos, um ADVANCED_BREP_SHAPE_REPRESENTATION por peça. readStepBreps lê geometria e topologia AP203, AP214 e AP242, incluindo montagens com suas transformações e nomes de produtos. Entidades desconhecidas são relatadas em warnings e seus rostos saltaram; nada é adivinhado.
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.)); A leitura desse arquivo deu uma parte cujo volume era 34097.52220392303 mm³, igual ao corpo escrito com 11 dígitos significativos.
Orçamento de tempo
O kernel é síncrono e é executado no thread do chamador. withBudget(ms, f) estabelece um prazo; loops longos (pares de faces de uma chamada booleana, divisão de faces, intersecção de superfície, mosaico) checkBudget, que lança BudgetExceeded. Os orçamentos aninhados mantêm o prazo anterior; sem orçamento, um cheque custa uma comparação.
withBudget(1, () => booleanBrep(makeSphere(10), makeBox(10, 10, 10), "union"))
// BudgetExceeded: the exact model exceeded its time budget of 1 ms Solução de problemas
| Sintoma | Causa | Consertar |
|---|---|---|
BooleanError | o resultado costurado não é um sólido múltiplo fechado (tangentes ou faces quase coincidentes) | mover um operando ligeiramente para fora da tangência; verifique ambos com validBrep primeiro |
BudgetExceeded | a operação demorou mais do que o seu orçamento | simplificar ou dar ao chamador um orçamento maior |
| RangeError de um primitivo | tamanho não positivo ou toro menor ≥ maior | por exemplo "o raio menor do toro deve ser menor que o raio maior" |
misturar borda em rejected | face muito estreita para o raio, fio de navalha ou parede inclinada | raio menor ou um chanfro |
| Parte STEP faltando faces | entidade não suportada no arquivo | ler warnings de readStepBreps |
| validateBrep relata problemas | erro de índice, orientação ou borda na superfície em um corpo construído | a emissão nomeia a entidade; nada é reparado automaticamente |