Documentazione
Visualizzazione
Gli strumenti di disegno su tela e il rendering di Three.js condividono la geometria principale mantenendo esplicito lo stato di modifica e riproduzione.
Tradotto automaticamente dall'inglese. Vedi l'originale in inglese
Componenti della vista
apps/desktop/src/viewport/index.ts esportazioni Editor2D, View3D, i tipi di oggetti di scena, gli identificatori degli strumenti disponibili e solidsFromProfiles. Entrambi i componenti riempiono il loro genitore: forniscono un contenitore con larghezza e altezza diverse da zero. Le entità CAD principali e i programmi CAM costituiscono il modello dati condiviso.
L'editor 2D esegue il rendering su Canvas 2D e mantiene la propria cronologia di selezione, fotocamera e comandi. Il visualizzatore 3D utilizza Three.js, controlli di orbita e trasformazione, processi mesh asincroni e riproduzione del programma. Il rendering di un percorso o di un solido è indipendente dal salvataggio o dalla verifica di un'operazione di produzione.
Contratto di integrazione
Editor2DProps richiede drawing, onChange, e selectedTool. Reinserire i disegni emessi nell'oggetto di scena. Il componente riconosce i propri oggetti documento emessi; la sostituzione del documento esternamente carica il nuovo disegno e ripristina lo stato dell'editor.
import { createSignal } from "solid-js"
import { Editor2D, type ToolId } from "./viewport/index.ts"
const [drawing, setDrawing] = createSignal(initialDrawing)
const [tool, setTool] = createSignal<ToolId>("select")
<Editor2D drawing={drawing()} onChange={setDrawing} selectedTool={tool()} /> La selezione esclude le entità bloccate e le entità su livelli bloccati. Le entità invisibili e i livelli nascosti sono esclusi dall'indice spaziale renderizzato. Le nuove entità ricevono identificatori univoci del documento e vengono assegnate a un livello visibile e sbloccato quando ne è disponibile uno.
Strumenti e gesti di disegno
Il registro degli strumenti dispone di impostazioni per selezione, linea, rettangolo, cerchio, ellisse, polilinea, arco, testo, quota, spostamento, rotazione, scala, specchio, offset, ritaglio e raccordo. AVAILABLE_TOOLS deriva da quelle fabbriche registrate. startTool riconosce inoltre chamfer attraverso la fabbrica degli strumenti di raccordo, ma lo smusso non è pubblicizzato in quella matrice. I consumatori dovrebbero utilizzare il registro vero e proprio per decidere quali strumenti abilitare.
- Zoom con rotella o pizzico; Trascina spazio, trascina il centro e trascina la panoramica verso destra.
Fsi adatta al disegno indicizzato. Elimina o Backspace rimuove la selezione sbloccata.Cmd/Ctrl+Zannulla;Cmd/Ctrl+Shift+ZoCmd/Ctrl+Yrifa.- Invio conferma una polilinea. L'Escape viene inviato allo strumento attivo per annullare il gesto corrente.
- Con il testo attivo, digitare i caratteri o Backspace prima del posizionamento; il testo iniziale è
Text.
Le posizioni del puntatore vengono convertite in coordinate mondiali prima dell'invio dello strumento. Lo snap combina l'indice spaziale, i candidati geometrici e una griglia dipendente dalla fotocamera; la tolleranza del colpo di selezione corrisponde a otto pixel dello schermo. Le macchine utensili producono comandi e anteprime anziché scrivere file o chiamare l'API.
3Rendering e riproduzione D
View3D accetta disegni, solidi, estrusione di profili opzionale, a cam.Program, dimensioni grezze e definizioni di utensili. Supporta le preimpostazioni prospettica, superiore, inferiore, anteriore, posteriore, sinistra, destra, isometrica e a quattro viste. Le modalità di visualizzazione sono ombreggiata, ombreggiata con bordi, wireframe e raggi X. Illuminazione, proprietà dei materiali, sezioni di ritaglio, griglia, assi e origine sono configurabili tramite oggetti di scena.
Controlla la riproduzione con playing, playbackTime in pochi secondi, playbackRate, e onPlaybackTimeChange. La riproduzione espande i cicli di foratura, tassella il movimento circolare/elicoidale, preserva il tempo di sosta e disegna distintamente i movimenti rapidi. Mappe degli utensili e geometria predefinita opzionale della taglierina, del gambo e del supporto; la geometria presunta è visivamente distinta.
I callback di selezione riportano un indice solido. I controlli di trasformazione emettono posizione, rotazione e ridimensionamento onTransformCommit; i chiamanti decidono come mantenere tale trasformazione. Le sovrapposizioni del percorso utensile possono mostrare punti ed etichette, filtri di tipo punto, centri dell'arco, raggi dell'arco e trasparenza del grezzo.
La riproduzione è una rappresentazione visiva
Il visualizzatore anima il programma fornito e disegna stock e strumenti. Non esegue asportazione di materiale. I controlli di collisione e di inviluppo macchina appartengono ai moduli di verifica CAM; la visione di un programma non costituisce approvazione della macchina.
Coordinate e unità
Le coordinate del disegno principale e le dimensioni del grezzo utilizzano i millimetri. Gli angoli di disegno e i componenti di rotazione di Three.js utilizzano i radianti; non applicare tale convenzione ai valori dell'asse rotante CAM o agli input di funzionalità che utilizzano esplicitamente i gradi. viewport/units.ts contiene aiutanti di conversione per millimetri e pollici visualizzati. Converti ai limiti di input/output in modo che lo snap, la geometria e il movimento del percorso utensile mantengano un sistema di unità coerente.
La 2fotocamera D mappa le coordinate del mondo su pixel CSS; le dimensioni della tela di supporto incorporano il rapporto pixel del dispositivo. Il ridimensionamento aggiorna la fotocamera e il buffer di backup ResizeObserver. La scala della fotocamera determina la spaziatura della griglia e le tolleranze dei colpi dello spazio sullo schermo.
La visualizzazione in pollici viene convertita esattamente con 25.4 mm per pollice e le lunghezze predefinite sono 3 decimali (apps/desktop/src/viewport/units.ts). Nell'editor 2D, ogni passo della ruota viene ingrandito di un fattore 1.15, la scala è compresa tra 0.001 e 100,000 e l'adattamento alla vista lascia un margine del 10% (editor2d/camera.ts).
Risorse e ciclo di vita
Il componente 2D annulla i fotogrammi di animazione in coda e disconnette il suo osservatore di ridimensionamento durante lo smontaggio. Il componente 3D rilascia listener di ridimensionamento e visibilità, controlli di orbita e trasformazione, meshworker, pianificazione delle animazioni, geometrie, materiali, sprite, mesh di strumenti e il renderer WebGL.
Un frame scheduler riunisce gli invalidamenti e richiede ulteriori frame mentre lo smorzamento o la riproduzione della telecamera ne hanno bisogno. I cambiamenti di visibilità sospendono il lavoro. Questa è una politica di pianificazione, non un budget di frame rate garantito per ogni modello e dispositivo.
Mappa dei moduli
editor2d/editor2d.tsx: componente controllato, invio del puntatore, fotocamera, selezione, cronologia e pittura su tela.editor2d/tools/: macchine a stati gestuali e costruzione di comandi.editor2d/camera.ts,render.ts, esnap-pipeline.ts: trasformazioni di coordinate, rendering di entità, selezione e orchestrazione degli snap.spatial/grid.ts: disegno indice spaziale.view3d/view3d.tsx: composizione della scena, controlli della fotocamera, selezione, trasformazioni, stock e strumenti.view3d/playback.ts,toolpath-overlays.ts, emodeling.ts: sequenza temporale del movimento, dati di sovrapposizione e conversione da profilo a solido.view3d/mesh-jobs.tsemesh-worker.ts: costruzione della geometria dello sfondo e proprietà del lavoro.
Disponibilità degli strumenti
ToolId descrive il vocabolario più ampio degli strumenti; AVAILABLE_TOOLS descrive il sottoinsieme registrato. Per gli strumenti interattivi, utilizzare startTool(id, lookup, context, text). La ricerca di selezione interroga le entità candidate; il contesto fornisce la selezione corrente e l'accesso alle entità; il testo fornisce il contenuto dell'annotazione.
Ritorna una fabbrica scomparsa undefined. Gestiscilo in modo esplicito anziché presentare uno strumento disabilitato o non implementato come modalità di modifica attiva. Gli strumenti che modificano la geometria esistente richiedono la selezione corrente e il contesto dell'entità; invocare una factory senza tali dipendenze non è sufficiente per una modifica utile.
Meshing e verifica
Per i solidi con un conteggio stimato dei vertici superiore a 50,000 e il supporto del browser Worker, il visualizzatore accoda la costruzione della mesh in un modulo di lavoro. I solidi più piccoli si intrecciano in modo sincrono. La coda mesh gestisce il completamento, i lavori obsoleti, gli errori dei lavoratori e la pulizia. La soglia è una stima utilizzata per la pianificazione, non un limite documentato per le dimensioni del modello.
bun test apps/desktop/src/viewport
bun run --filter @cadcamfun/desktop typecheck I test logici riguardano gli assistenti di rendering, i gesti degli strumenti, l'indicizzazione spaziale, la riproduzione e le sovrapposizioni. Il comportamento del browser/WebGL dipende anche dall'ambiente grafico; ispezionare l'effettiva interazione della finestra quando si modificano i controlli della telecamera, il ciclo di vita della scena o il rendering.
Esempio di riproduzione controllata
Un genitore può possedere i controlli di trasporto senza duplicare la sequenza temporale del movimento dello spettatore. Questo componente accetta un programma CAM già costruito e controlla il tempo, lo stato di riproduzione, la velocità e la preimpostazione del viewport. I suoi percorsi di importazione presuppongono un file direttamente sotto apps/desktop/src.
import { createSignal } from "solid-js"
import { cam } from "@cadcamfun/core"
import { View3D } from "./viewport/index.ts"
export function ProgramPreview(props: { program: cam.Program }) {
const [seconds, setSeconds] = createSignal(0)
const [playing, setPlaying] = createSignal(false)
return <div style={{ height: "600px" }}>
<button onClick={() => setPlaying(value => !value)}>Play / pause</button>
<button onClick={() => { setSeconds(0); setPlaying(true) }}>Restart</button>
<View3D
program={props.program}
preset="isometric"
playing={playing()}
playbackTime={seconds()}
playbackRate={1}
onPlaybackTimeChange={setSeconds}
stock={{ origin: { x: 0, y: 0, z: -10 }, size: { x: 100, y: 80, z: 10 } }}
/>
</div>
} Il generatore di riproduzione inizia dall'origine, espande i cicli in mosse e calcola le durate dalla lunghezza del viaggio e dall'avanzamento. La sua velocità rapida predefinita è 5,000 mm/min e la tolleranza predefinita per la tassellatura dell'arco è 0.1 mm. Si tratta di ipotesi di anteprima, non dell'accelerazione della macchina misurata o dei tempi del controller. I comandi di pausa mantengono i secondi dichiarati; i commenti e le voci di solo orientamento non aggiungono la corsa lineare.
I colori degli strumenti vengono assegnati dalla prima occorrenza di ciascun identificatore di strumento e mantenuti nei suoi percorsi. Fornire una mappa strumenti/strumento predefinito per la geometria dell'assieme; un percorso colorato da solo non stabilisce le dimensioni della taglierina o del supporto utilizzati dalla verifica.
Modifica di ricette e limiti attuali dello strumento
| Operazione | Gesto e precondizioni | Comportamento attuale |
|---|---|---|
| Offset | Seleziona un'entità supportata, quindi trascina; Shift sceglie invece l'entità sotto il cursore. | Linee/polilinee/rettangoli producono un risultato polilinea. Le implementazioni di cerchi e archi traducono il centro mantenendo il raggio; questo strumento non è un'operazione generale di offset concentrico per le curve. |
| Taglia/estende | Selezionare prima le entità sorgente e limite, attivare Taglia e fare clic sulla destinazione. Alt seleziona la modalità di estensione. | L'implementazione ricerca le intersezioni nelle altre entità selezionate. Cambia linee e polilinee; i tipi di target non supportati o le intersezioni mancanti non producono alcuna modifica. |
| Filetto/smusso | Scegli due linee che si intersecano. Shift passa allo smusso. | Lo strumento condiviso utilizza un raggio iniziale di 5 mm e sostituisce la coppia con linee tagliate e una polilinea di collegamento. Non si tratta di un raccordo a bordo pieno arbitrario. |
| Trasformare un solido | Fornire onTransformCommit, seleziona una mesh, quindi attiva trasla/ruota/scala. | Il callback riporta l'indice solido e i valori di trasformazione. La selezione e la trasformazione dei gizmo sono disabilitati nella modalità a quattro visualizzazioni. |
Questi dettagli provengono dalle implementazioni dei gesti piuttosto che dalle etichette delle tavolozze. Esamina l'anteprima prima di confermare e utilizza Annulla se il risultato differisce dalla geometria desiderata. Uno strumento che non restituisce alcun comando può significare che i suoi prerequisiti geometrici non sono stati soddisfatti, non che l'editor ha perso l'evento del puntatore.
Errori di rendering e mesh
Per impostazione predefinita, la coda mesh in background ammette al massimo 128 lavori in sospeso, viene eseguito uno alla volta e ha un timeout predefinito di 15 secondi per lavoro. Il ripristino di una scena termina il lavoratore e cancella il lavoro in coda; le risposte obsolete vengono ignorate. Le risposte dell'operatore non valide, gli errori di decodifica dei messaggi, i timeout e gli errori di capacità della coda segnalano errori attraverso la richiamata della coda.
| Sintomo | Azione |
|---|---|
| Tela vuota senza geometria | Assegna al genitore una dimensione diversa da zero, controlla la visibilità dell'entità/livello e adatta la vista. |
| Non è possibile selezionare nulla | Controlla i blocchi di entità/livello in 2D; controlla la modalità a quattro visualizzazioni e trasforma lo stato in 3D. |
| Timeout mesh o coda piena | Riduci la complessità della scena o il numero di solidi inviati simultaneamente e controlla l'errore dell'operatore. Un batch non riuscito viene cancellato anziché installato parzialmente come lavoro completato. |
| Il tempo di riproduzione sembra sbagliato | Controlla i feed del programma, gli spostamenti di pausa, le ipotesi di velocità rapida e se un programma modificato reimposta il tempo principale. |
| WebGL non è disponibile | Utilizza un ambiente grafico supportato e controlla lo stato di rendering non disponibile del componente; i test logici non possono dimostrare la disponibilità della GPU. |
I test rilevanti includono editor2d/tools/offset.test.ts, annotation-transform.test.ts, spatial/grid.test.ts, view3d/playback.test.ts, e toolpath-overlays.test.ts. L'implementazione della coda mesh è view3d/mesh-jobs.ts.
Espositori in dettaglio
L'editor lavora sempre in millimetri. Viene convertito solo ciò che l'utente legge e digita, utilizzando i fattori esatti riportati di seguito. L'unità propria di un disegno memorizzato rimane mm o inch; le unità extra sono solo scelte di visualizzazione.
| Unità | Etichetta | mm per unità | Decimali predefiniti | Unità di programma codice G |
|---|---|---|---|---|
mm | mm | 1 | 3 | mm |
um | µm | 0.001 | 1 | mm |
cm | cm | 10 | 4 | mm |
m | m | 1000 | 6 | mm |
inch | pollice | 25.4 | 4 | pollice |
thou | tu | 0.0254 | 2 | pollice |
import { formatLength, parseLength, formatAngle, programUnitsOf } from "./units"
formatLength(25.4, "inch") // "1.0000 inch"
formatLength(12.5) // "12.500 mm"
formatLength(0.0254, "thou") // "1.00 thou"
parseLength("2 in", "inch") // 50.8 (a trailing unit word is ignored)
parseLength("abc") // undefined
formatAngle(Math.PI / 2) // "90.0°"
programUnitsOf("thou") // "inch" parseLength rimuove un suffisso alfabetico finale (incluso µ e °) e interpreta il numero nell'unità di visualizzazione corrente. Il suffisso non viene utilizzato per scegliere un'unità, quindi digitarlo 2 mm mentre la visualizzazione è in pollici restituisce 50.8 mm. Restituzioni di input vuote, non numeriche e infinite undefinede in questo caso gli editor dovrebbero mantenere il valore precedente.
2D fotocamera e griglia
worldToScreen capovolge Y in modo che il mondo +Y punti verso l'alto sullo schermo.| Costante/funzione | Valore | Comportamento |
|---|---|---|
ZOOM_STEP | 1.15 | Fattore per passo ruota; zoomAt mantiene fisso il punto del mondo sotto il cursore. |
MIN_SCALE / MAX_SCALE | 0.001 / 100,000 px per mm | La scala è limitata a questo intervallo. |
FIT_MARGIN | 0.1 | Frazione dell'area visibile mantenuta come margine da cameraForBounds. |
createCamera() | centro (0, 0), scala 1, 800 × 600 | Fotocamera iniziale prima del primo ridimensionamento. |
gridStep(scale, major = 10, minPixels = 8) | 1-2-5 scala | Il passaggio più piccolo che mantiene i punti della griglia ad almeno 8 px di distanza. |
const camera = createCamera({ x: 0, y: 0 }, 2, 800, 600) // 2 px per mm
worldToScreen(camera, { x: 10, y: 10 }) // { x: 420, y: 280 }
screenToWorld(camera, { x: 420, y: 280 }) // { x: 10, y: 10 }
gridStep(2) // 5 -> 5 mm apart = 10 px
gridStep(0.5) // 20 -> 20 mm apart = 10 px Il rendering seleziona le entità rispetto a visibleBounds(camera). Lo snap evita inoltre la scansione dell'intero disegno: una griglia spaziale uniforme restituisce entità i cui limiti rientrano nella tolleranza di snap più un margine candidato di 2 mm e solo quelle vengono passate al nucleo findSnap. In questo modo il puntatore si muove velocemente nei disegni con molte entità.
Riferimento allo snap
I tipi di snap vengono provati in ordine di priorità. L'ordine predefinito corrisponde all'editor precedente: endpoint, midpoint, center, intersection, perpendicular, tangent, nearest, e quadrant. I punti finali sono i vertici dell'entità di origine, non la sua tassellatura.
| Collocamento | Senso |
|---|---|
enabled | Interruttore principale; false disabilita tutti gli snap. |
types | Tipi di snap abilitati, prima la priorità più alta. |
tolerance | Raggio di scatto in millimetri; non dipende dallo zoom. |
gridEnabled, gridSpacing | Esegui lo snap alla griglia quando non è applicabile lo snap all'oggetto. |
referencePoint | Il punto da cui si trae. perpendicular e tangent non trovare nulla senza di essa. |
La pipeline restituisce lo snap, gli ID delle entità sotto il cursore (prima la più vicina, utilizzata dallo strumento di selezione) e il numero di candidati considerati.
Come viene cronometrata la riproduzione del percorso utensile
buildPlayback(program, rapidRate = 5000, tolerance = 0.1) converte un programma CAM in segmenti temporizzati. La durata di ogni mossa è la sua lunghezza divisa per la sua alimentazione (o per la velocità rapida per le rapide), moltiplicata per 60, ovvero i secondi. Le abitazioni aggiungono il proprio tempo senza muoversi. Commenti, spostamenti di orientamento e cicli fissi non vengono disegnati come segmenti. Gli archi sono divisi in accordi la cui sagitta rimane all'interno tolerance (tra 2 e 65, 536 corde per arco) e Z è interpolato lungo l'arco per le eliche.
const playback = buildPlayback(program) // rapids at 5000 mm/min
playback.duration // total seconds
positionAt(playback, 12.5) // tool position at t = 12.5 s
toolAt(playback, 12.5) // toolId cutting at that time
toolColors(program) // Map toolId -> colour, first use order
// A 10 mm feed move at 600 mm/min lasts 10 / 600 × 60 = 1 s.
// The same 10 mm as a rapid lasts 10 / 5000 × 60 = 0.12 s. segmentIndexAt trova il segmento in riproduzione mediante la ricerca binaria, quindi la ricerca è economica anche per programmi lunghi. La ricerca oltre la fine restituisce la posizione finale e toolAt quindi segnala l'ultimo strumento. Il tempo di riproduzione è una stima visiva basata sui feed programmati; ignora l'accelerazione della macchina, quindi una macchina reale impiega più tempo.
Pratiche di visualizzazione
- Converti al limite: archivia e calcola in millimetri e radianti e formatta solo per la visualizzazione
formatLengtheformatAngle. - Non riutilizzare mai una lunghezza analizzata dopo
parseLengthritornaundefined; mantieni il valore precedente e mostra un suggerimento di convalida. - Quando si aggiunge uno strumento di disegno, registrarlo nella tabella della fabbrica degli strumenti in modo che la barra degli strumenti, le scorciatoie e i test lo indirizzino con lo stesso ID.
- Mantieni le query dei candidati istantanee spaziali. Passare ogni entità a
findSnapsu ogni movimento del puntatore sconfigge l'indice. - Tratta la durata della riproduzione come un'anteprima, non come una citazione del tempo di ciclo.
Hit testing su larga scala: la griglia spaziale
L'editor 2D ha come target 60 fps con 10,000 entità, quindi gli hit testing e l'abbattimento non scansionano mai ogni entità per evento puntatore. viewport/spatial/grid.ts mantiene una griglia uniforme: ogni elemento è registrato in ogni cella toccata dal riquadro di delimitazione e una query restituisce tutti gli elementi i cui limiti intersecano il riquadro di query, in ordine di inserimento. Il risultato è esatto, mai un campione.
| Collocamento | Valore | Perché |
|---|---|---|
| Dimensione cella predefinita | 50 unità mondiali (mm) | Adatto a un disegno di circa 1 m di diametro |
| Dimensione minima della cella | 1e-6 | Protegge da dimensioni pari a zero o negative, che potrebbero ripetersi in loop per sempre |
| Limite di celle per articolo | 4,096 | Gli elementi più grandi (una lunga linea sul foglio) vengono tracciati lateralmente invece che per cella |
| Metodo | Comportamento |
|---|---|
build(items) | Ricostruisci da zero |
upsert(id, item) | Inserisci o sostituisci un elemento con l'id |
remove(id) | Rimuovere; gli ID sconosciuti vengono ignorati |
query(bounds) | Id i cui limiti intersecano la scatola |
Vengono visitate le celle toccate dalla casella di query tratteggiata; A e la linea lunga vengono restituiti perché i loro limiti la intersecano, B no.
3Coda di meshing D
I solidi vengono meshati in un Web Worker in modo che il thread dell'interfaccia utente non si blocchi mai. MeshWorkerQueue in view3d/mesh-jobs.ts esegue un lavoro alla volta:
| Regola | Valore | Messaggio in caso di fallimento |
|---|---|---|
| Capacità (in coda + in esecuzione) | 128 | La coda mesh 3D è piena. Ridurre la complessità della scena. |
| Timeout per lavoro | 15 s | 3Mesh D scaduto. Ridurre la complessità della scena. |
| Errore del lavoratore | — | Il messaggio del lavoratore o "Il lavoratore mesh si è arrestato in modo imprevisto". |
| Risposta indecifrabile | — | Il meshworker non è riuscito a decodificare la sua risposta. |
| Pessima geometria | le posizioni devono essere Float32Array, indici Uint32Array | Il lavoratore mesh ha restituito una geometria non valida. |
Qualsiasi errore termina il lavoratore e cancella l'intera coda, quindi il lavoro sulla scena stantio non arriva mai dopo una modifica più recente; l'invio successivo avvia un nuovo lavoratore. Le risposte corrispondono all'ID lavoro, quindi una risposta tardiva da parte di un lavoratore licenziato viene ignorata.
2Implementazioni dello strumento D
| File | Utensili |
|---|---|
tools/two-point.ts | linea, rettangolo, cerchio per diametro, ellisse |
tools/chained.ts | polilinea, arco di tre punti |
tools/fillet-chamfer.ts | arrotondare o smussare l'angolo tra due linee |
tools/offset.ts | sfalsare una polilinea, un rettangolo, un cerchio o un arco di una distanza |
tools/trim.ts | tagliare ed estendere |
tools/select.ts | fare clic, inserire nella casella e aggiungere/rimuovere la selezione |
tools/annotation-transform.ts | spostare e trasformare le annotazioni |
Ogni strumento è una piccola macchina statale onPointerDown, onPointerMove e onPointerUp, creato da una fabbrica in tools/index.ts, uno per voce della tavolozza. Le posizioni del puntatore passano attraverso snap-pipeline.ts prima che uno strumento li veda.