Vai al contenuto
CADCAMFUN
Documentazione

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.

FileLineeRuolo
cad/solid.ts659Schemi solidi (Scatola, Cilindro, Sfera, Cono, Toro, Estrusione, Rivoluzione), meshOf, meshVolume, meshBounds
cad/csg.ts459Booleani BSP, classificatore convesso, trasla/ruota/unisci
cad/mesh-clean.ts626saldatura, riparazione di giunzioni a T, unione complanare, ritriangolazione
cad/mesh-topology.ts110varietà, conchiglie, genere, volume, area
cad/triangulate.ts383triangolazione di poligoni con fori
Piastra forata con borchia forata Trascina per orbitare · scorri per ingrandire · trascina con il tasto destro per eseguire la panoramica
Output booleanMesh reale: una casella 60 × 40 × 10 meno quattro fori Ø6 (sottrazione booleanAll), unita con un risalto Ø20 × 8, quindi perforata Ø10. 640 triangoli; meshTopology riporta un solido chiuso, 1 shell, genere 5, V 23981.4 mm³.

Il tipo Mesh e le primitive

solid.ts
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
SolidoCampiLimiti
Scatolaorigine, dimensione {x, y, z}taglie > 0
Cilindroorigine, raggio, altezza, segmenti, asse?segmenti 3–512; asse z | x| sì
Sferacentro, raggio, anellisquilla 2–256
Conoorigine, baseRadius, topRadius, altezza, segmenti, asse?raggio superiore ≥ 0; segmenti 3–512
Torocentro, raggio maggiore, raggio minore, rotazione?, segmenti maggiori, segmenti minori, asse?3–512 e 3–256
Estrudereprofilo (≥ 3 punti, non chiuso), altezza, origine?profilo in XY
Ruotareprofilo (≥ 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.
GuardiaValoreMessaggio di errore
la tolleranza deve essere positiva e finita—La tolleranza della mesh deve essere positiva e finita
segmenti per curva65 536La tolleranza della mesh supera il budget di suddivisione
righe della griglia × colonne (sfera, toro, rivoluzione)1 000 000La 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.

  1. If either mesh is empty, or the bounding boxes do not meet (within tolerance), answer directly: union = merge, subtract = a, intersect = empty.
  2. Costruisci i classificatori di A e B (piani convessi o BSP).
  3. 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.
  4. Subtract and intersect follow the classic a.clipTo(b), b.clipTo(a), b.invert() sequence on polygon lists, without copying trees.
  5. 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.
csg.ts
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:

RisultatoVolume, mm³Triangoli
sola sfera7 063.84 (esatto 7 238.23)624
cubo ∩ sfera882.98112
cubo ∪ sfera14 180.86—
cubo − sfera7 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.

cubo − sfera Trascina per orbitare · scorri per ingrandire · trascina con il tasto destro per eseguire la panoramica
Risultato della sottrazione: il cubo con un'ottava sfera scavata nel suo angolo.
cubo ∩ sfera Trascina per orbitare · scorri per ingrandire · trascina con il tasto destro per eseguire la panoramica
Risultato dell'intersezione: l'ottavo della sfera che si trova all'interno del cubo.

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.
meshTopology(bored) — output reale
{"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:
Produzione reale
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

SintomoCausaAggiustare
Il risultato booleano presenta buchi o facce invertiteun ingresso è aperto o avvolto in senso orariocontrolla entrambi gli input con meshTopology: BoundaryEdges e MisorientedEdges devono essere 0
manca o è raddoppiata una faccia condivisa da entrambi gli operandile 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 suddivisionetolleranza troppo fine per il raggioutilizzare le tolleranze preimpostate (da 0.1 a 0.0005 mm)
il volume differisce dalla formulasfaccettatura con tolleranza grossolanamesh più fine o utilizzare il kernel B-rep per proprietà di massa esatte
Booleano lento su molti strumentiunione di strumenti costruiti per primisottrai gli strumenti uno per uno (booleanAll fa questo): ogni strumento convesso è una manciata di piani