Documentazione
Kernel mesh e CSG
Mesh a triangolo chiuso da solidi parametrici, booleane BSP con percorso veloce convesso, controlli di pulizia e topologia.
Tradotto automaticamente dall'inglese. Vedi l'originale in inglese
Cos'è il kernel mesh
Il kernel mesh funziona su mesh a triangolo chiuso: le costruisce da primitive parametriche (meshOf), li misura (meshVolume, meshBounds, meshTopology) e li combina con i valori booleani (booleanMesh, booleanAll). È ciò che mostra il viewport, ciò che la macchina dei generatori CAM e ciò che scrive l'esportazione STL.
Non è una rappresentazione esatta del confine. Un cilindro tagliato rimane un cilindro sfaccettato e non esiste una topologia faccia su cui raccordare o misurare. Per facce esatte, raccordi, proprietà di massa e STEP, il Kernel B-rep è un pezzo di codice separato.
| File | Linee | Ruolo |
|---|---|---|
cad/solid.ts | 659 | Schemi solidi (Scatola, Cilindro, Sfera, Cono, Toro, Estrusione, Rivoluzione), meshOf, meshVolume, meshBounds |
cad/csg.ts | 459 | Booleani BSP, classificatore convesso, trasla/ruota/unisci |
cad/mesh-clean.ts | 626 | saldatura, riparazione di giunzioni a T, unione complanare, ritriangolazione |
cad/mesh-topology.ts | 110 | varietà, conchiglie, genere, volume, area |
cad/triangulate.ts | 383 | triangolazione di poligoni con fori |
Il tipo Mesh e le primitive
export interface Mesh {
readonly positions: Float32Array // x, y, z per vertex
readonly indices: Uint32Array // three per triangle, counter-clockwise seen from outside
}
export const meshOf: (solid: Solid, tolerance?: number /* 0.1 mm */) => Mesh
export const meshVolume: (mesh: Mesh) => number // signed; positive when outward-facing
export const meshBounds: (mesh: Mesh) => SolidBounds | Solido | Campi | Limiti |
|---|---|---|
| Scatola | origine, dimensione {x, y, z} | taglie > 0 |
| Cilindro | origine, raggio, altezza, segmenti, asse? | segmenti 3–512; asse z | x| sì |
| Sfera | centro, raggio, anelli | squilla 2–256 |
| Cono | origine, baseRadius, topRadius, altezza, segmenti, asse? | raggio superiore ≥ 0; segmenti 3–512 |
| Toro | centro, raggio maggiore, raggio minore, rotazione?, segmenti maggiori, segmenti minori, asse? | 3–512 e 3–256 |
| Estrudere | profilo (≥ 3 punti, non chiuso), altezza, origine? | profilo in XY |
| Ruotare | profilo (≥ 2 punti in XZ), angolo, segmenti? | circa Z; segmenti 3–512, predefinito 16 |
segments e rings sono minimi: meshOf li alza finché l'errore dell'accordo non è compreso tolerance, using step = 4·asin(√(min(1, tol/r)/2)). Two budgets stop runaway tolerances.
| Guardia | Valore | Messaggio di errore |
|---|---|---|
| la tolleranza deve essere positiva e finita | — | La tolleranza della mesh deve essere positiva e finita |
| segmenti per curva | 65 536 | La tolleranza della mesh supera il budget di suddivisione |
| righe della griglia × colonne (sfera, toro, rivoluzione) | 1 000 000 | La tolleranza della mesh supera il budget del vertice |
Un cilindro Ø6 con segments: 24 con tolleranza 0.05 è uscito con 96 triangoli (24 lati, due 24-gon caps); un Ø20 uno con 128, perché il raggio più grande necessitava di 32 segmenti per rimanere all'interno di 0.05 mm.
Booleani mediante partizionamento binario dello spazio
Ogni operando diventa un classificatore. Una mesh generale ottiene un albero BSP; una mesh convessa (chiusa, connessa, ogni bordo convesso) è costituita solo dai suoi piani facciali distinti, quindi una scatola è composta da sei piani e una sfera di diecimila triangoli è classificata senza costruire la catena quadratica in cui degenera un BSP di un solido convesso. I poligoni vengono classificati come elenchi e un poligono libero dal riquadro di delimitazione dell'altro operando viene mantenuto o eliminato senza camminare su nulla.
- If either mesh is empty, or the bounding boxes do not meet (within tolerance), answer directly: union = merge, subtract = a, intersect = empty.
- Costruisci i classificatori di A e B (piani convessi o BSP).
- Unione: mantieni A all'esterno di B, B all'esterno di A e rilascia le facce di B coincidenti con quelle di A che puntano nella stessa direzione, in modo che una faccia condivisa venga mantenuta una volta.
- Subtract and intersect follow the classic a.clipTo(b), b.clipTo(a), b.invert() sequence on polygon lists, without copying trees.
- Pulisci la zuppa di poligoni: salda i punti entro max(10·eps, 1e-9·size), chiudi le giunzioni a T, chiudi gli spazi fino a 1e-4·size tra le scaglie, unisci frammenti complanari e ritriangola.
export type BooleanOp = "union" | "subtract" | "intersect"
export interface CsgOptions {
/** Distance below which a point counts as on a plane, mm. Default 1e-7 × the larger extent. */
readonly tolerance?: number
/** Merge coplanar fragments and re-triangulate (default true). */
readonly mergeCoplanar?: boolean
}
export const booleanMesh: (a: Mesh, b: Mesh, op: BooleanOp, options?: CsgOptions) => Mesh
/** Union reduced as a balanced tree; subtract and intersect fold left to right. */
export const booleanAll: (meshes: ReadonlyArray<Mesh>, op: BooleanOp, options?: CsgOptions) => Mesh
export const translateMesh: (mesh: Mesh, dx: number, dy: number, dz: number) => Mesh
export const rotateMesh: (mesh: Mesh, axis: V3, radians: number, origin?: V3) => Mesh
export const mergeMeshes: (meshes: ReadonlyArray<Mesh>) => Mesh Il conteggio dei triangoli cresce con le caratteristiche, non con il numero di booleani: la fase di unione ricolloca le parti complanari nelle facce intere. Nella piastra sopra, la scatola aveva 12 triangoli, dopo quattro fori 412, dopo il risalto 540, dopo il foro 640; l'intera catena è stata eseguita in 96 ms.
Unione, sottrazione, intersezione su input curvo
A 20 mm cube at the origin against a sphere of radius 12 centred on its far corner (20, 20, 20), meshed at tolerance 0.2 (624 triangles). Real volumes:
| Risultato | Volume, mm³ | Triangoli |
|---|---|---|
| sola sfera | 7 063.84 (esatto 7 238.23) | 624 |
| cubo ∩ sfera | 882.98 | 112 |
| cubo ∪ sfera | 14 180.86 | — |
| cubo − sfera | 7 117.02 | — |
Controlla: 8 000 + 7 063.84 − 882.98 = 14 180.86 e 8 000 − 882.98 = 7 117.02, quindi i tre risultati sono coerenti tra loro secondo la centesimo. La mesh della sfera stessa è 2.4 % sotto la sfera esatta, che è la sfaccettatura di una tolleranza grossolana, non di un errore booleano.
Controllo della topologia
meshTopology conta vertici, bordi e triangoli, trova bordi, bordi non molteplici e orientati male, triangoli e gusci degenerati e deriva la caratteristica e il genere di Eulero. describeTopology stampa il riepilogo di una riga utilizzato dall'assistente e dalla finestra.
{"vertices":312,"triangles":640,"edges":960,"boundaryEdges":0,"nonManifoldEdges":0,
"misorientedEdges":0,"degenerateTriangles":0,"shells":1,"eulerCharacteristic":-8,"genus":5,
"closed":true,"solid":true,"volume":23981.43509870267,"area":8238.640705862534}
// describeTopology → "closed solid, 1 shell, genus 5, 640 triangles, V 23981.4 mm³, A 8238.6 mm²" V − E + F = 312 − 960 + 640 = −8 = 2 − 2g, so g = 5: the four drilled holes plus the bore, which runs through the boss and the plate.
Triangolazione poligonale
triangulatePolygon(outer, holes) restituisce l'indice triplo nella concatenazione dell'anello esterno e dei fori. Un quadrato 4 × 4 con un foro 2 × 2 dà otto triangoli:
triangulatePolygon(
[{x:0,y:0},{x:4,y:0},{x:4,y:4},{x:0,y:4}],
[[{x:1,y:1},{x:1,y:3},{x:3,y:3},{x:3,y:1}]])
// [[0,4,5],[7,4,0],[3,0,5],[7,0,1],[2,3,5],[6,7,1],[2,5,6],[6,1,2]] triangulatePolygonChecked ritorna undefined invece di un risultato parziale quando l'input non può essere triangolato (anelli autointersecanti, fori all'esterno dell'anello esterno).
Risoluzione dei problemi
| Sintomo | Causa | Aggiustare |
|---|---|---|
| Il risultato booleano presenta buchi o facce invertite | un ingresso è aperto o avvolto in senso orario | controlla entrambi gli input con meshTopology: BoundaryEdges e MisorientedEdges devono essere 0 |
| manca o è raddoppiata una faccia condivisa da entrambi gli operandi | le facce sono quasi ma non esattamente coincidenti (più distanti rispetto alla tolleranza) | aggancia gli operandi allo stesso piano o aumenta CsgOptions.tolerance |
| RangeError: la tolleranza della mesh supera il budget di suddivisione | tolleranza troppo fine per il raggio | utilizzare le tolleranze preimpostate (da 0.1 a 0.0005 mm) |
| il volume differisce dalla formula | sfaccettatura con tolleranza grossolana | mesh più fine o utilizzare il kernel B-rep per proprietà di massa esatte |
| Booleano lento su molti strumenti | unione di strumenti costruiti per primi | sottrai gli strumenti uno per uno (booleanAll fa questo): ogni strumento convesso è una manciata di piani |