Saltar al contenido
CADCAMFUN
Documentos

Documentación

Ventana gráfica

Las herramientas de dibujo de Canvas y el renderizado de Three.js comparten la geometría central y al mismo tiempo mantienen explícito el estado de edición y reproducción.

La traducción automática no está disponible ahora; el texto está en inglés con la interfaz en tu idioma. Ver el original en inglés

Componentes de la ventana gráfica

apps/desktop/src/viewport/index.ts exportaciones Editor2D, View3D, sus tipos de accesorios, identificadores de herramientas disponibles y solidsFromProfiles. Ambos componentes llenan su padre: proporcionan un contenedor con un ancho y alto distintos de cero. Las entidades CAD principales y los programas CAM son el modelo de datos compartido.

El editor 2D renderiza en Canvas 2D y mantiene su propio historial de selección, cámara y comandos. El visor 3D utiliza Three.js, controles de órbita y transformación, trabajos de malla asíncronos y reproducción de programas. Renderizar un camino o un sólido es independiente de guardarlo o verificar una operación de fabricación.

Contrato de integración

Editor2DProps requiere drawing, onChange, y selectedTool. Introduzca los dibujos emitidos nuevamente en el accesorio. El componente reconoce sus propios objetos de documento emitidos; reemplazar el documento externamente carga el nuevo dibujo y restablece el estado del editor.

Editor 2D controlado
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 selección excluye entidades bloqueadas y entidades en capas bloqueadas. Las entidades invisibles y las capas ocultas se excluyen del índice espacial renderizado. Las nuevas entidades reciben identificadores únicos de documentos y se asignan a una capa visible y desbloqueada cuando hay una disponible.

Herramientas de dibujo y gestos.

El registro de herramientas tiene fábricas para seleccionar, línea, rectángulo, círculo, elipse, polilínea, arco, texto, dimensión, movimiento, rotación, escala, espejo, desplazamiento, recorte y empalme. AVAILABLE_TOOLS se deriva de aquellas fábricas registradas. startTool además reconoce chamfer a través de la fábrica de herramientas de filete, pero el chaflán no se anuncia en esa matriz. Los consumidores deben utilizar el registro real para decidir qué herramientas habilitar.

  • Zooms con rueda o pellizco; Arrastre con espacio, arrastre con el centro y arrastre con la derecha.
  • F se ajusta al dibujo indexado. Eliminar o Retroceso elimina la selección desbloqueada.
  • Cmd/Ctrl+Z deshace; Cmd/Ctrl+Shift+Z o Cmd/Ctrl+Y rehace.
  • Enter confirma una polilínea. Escape se envía a la herramienta activa para cancelar su gesto actual.
  • Con el texto activo, escriba caracteres o Retroceso antes de colocarlo; el texto inicial es Text.

Las posiciones del puntero se convierten en coordenadas mundiales antes del envío de la herramienta. El ajuste combina el índice espacial, candidatos geométricos y una cuadrícula dependiente de la cámara; la tolerancia de selección corresponde a ocho píxeles de pantalla. Las máquinas de herramientas producen comandos y vistas previas en lugar de escribir archivos o llamar a la API.

3D renderizado y reproducción

View3D acepta dibujos, sólidos, extrusión de perfil opcional, un cam.Program, dimensiones de stock y definiciones de herramientas. Admite ajustes preestablecidos de perspectiva, superior, inferior, frontal, posterior, izquierda, derecha, isométrica y de cuatro vistas. Los modos de visualización son sombreado, sombreado con bordes, estructura alámbrica y rayos X. La iluminación, las propiedades de los materiales, las secciones de recorte, la cuadrícula, los ejes y el origen se pueden configurar mediante accesorios.

Controla la reproducción con playing, playbackTime en segundos, playbackRate, y onPlaybackTimeChange. La reproducción amplía los ciclos de perforación, tesela el movimiento circular/helicoidal, preserva el tiempo de permanencia y dibuja movimientos rápidos claramente. Mapas de herramientas y un cortador predeterminado opcional que proporciona geometría de cortador, vástago y soporte; La geometría supuesta se distingue visualmente.

Las devoluciones de llamada de selección informan un índice sólido. Los controles de transformación emiten posición, rotación y escala a través de onTransformCommit; las personas que llaman deciden cómo persistir esa transformación. Las superposiciones de trayectorias de herramientas pueden mostrar puntos y etiquetas, filtros de tipo de punto, centros de arco, radios de arco y transparencia del material.

La reproducción es una representación visual.

El espectador anima el programa suministrado y extrae material y herramientas. No realiza remoción de material. Las comprobaciones de colisiones y envolventes de máquinas pertenecen a los módulos de verificación CAM; Ver un programa no constituye la aprobación de la máquina.

Coordenadas y unidades

Las coordenadas del dibujo central y los tamaños de stock utilizan milímetros. Los ángulos de dibujo y los componentes de rotación de Three.js utilizan radianes; no aplique esa convención a los valores del eje giratorio CAM o a las entradas de funciones que utilizan grados explícitamente. viewport/units.ts contiene ayudas de conversión para milímetros y pulgadas mostrados. Convierta en los límites de entrada/salida para que el ajuste, la geometría y el movimiento de la trayectoria de herramienta conserven un sistema de unidades consistente.

La cámara 2D asigna coordenadas mundiales a píxeles CSS; Las dimensiones del lienzo de respaldo incorporan la proporción de píxeles del dispositivo. Cambiar el tamaño actualiza la cámara y el búfer de respaldo a través de ResizeObserver. La escala de la cámara determina el espaciado de la cuadrícula y las tolerancias de impacto del espacio de la pantalla.

La visualización en pulgadas convierte exactamente 25.4 mm por pulgada y las longitudes predeterminadas son 3 decimales (apps/desktop/src/viewport/units.ts). En el editor 2D, cada paso de la rueda aumenta un factor de 1.15, la escala se fija entre 0.001 y 100,000, y el ajuste para ver deja un margen de 10% (editor2d/camera.ts).

Recursos y ciclo de vida

El componente 2D cancela los fotogramas de animación en cola y desconecta su observador de cambio de tamaño al desmontar. El componente 3D lanza oyentes de cambio de tamaño y visibilidad, controles de órbita y transformación, trabajadores de malla, programación de animaciones, geometrías, materiales, sprites, mallas de herramientas y el renderizador WebGL.

Un programador de fotogramas fusiona invalidaciones y solicita más fotogramas mientras la amortiguación o la reproducción de la cámara los necesita. Los cambios de visibilidad suspenden el trabajo. Esta es una política de programación, no un presupuesto de velocidad de fotogramas garantizado para cada modelo y dispositivo.

Mapa del módulo

  • editor2d/editor2d.tsx: componente controlado, envío de puntero, cámara, selección, historial y pintura de lienzo.
  • editor2d/tools/: máquinas de estados gestuales y construcción de comandos.
  • editor2d/camera.ts, render.ts, y snap-pipeline.ts: transformaciones de coordenadas, representación de entidades, selección y orquestación de instantáneas.
  • spatial/grid.ts: dibujo de índice espacial.
  • view3d/view3d.tsx: composición de escena, controles de cámara, selección, transformaciones, stock y herramientas.
  • view3d/playback.ts, toolpath-overlays.ts, y modeling.ts: línea de tiempo de movimiento, datos superpuestos y conversión de perfil a sólido.
  • view3d/mesh-jobs.ts y mesh-worker.ts: construcción de geometría de fondo y propiedad del trabajo.

Disponibilidad de herramientas

ToolId describe el vocabulario más amplio de herramientas; AVAILABLE_TOOLS describe el subconjunto registrado. Para herramientas interactivas, utilice startTool(id, lookup, context, text). La búsqueda de selección consulta entidades candidatas; el contexto proporciona la selección actual y el acceso a la entidad; El texto proporciona el contenido de la anotación.

Vuelve una fábrica desaparecida undefined. Maneje eso explícitamente en lugar de presentar una herramienta deshabilitada o no implementada como un modo de edición activo. Las herramientas que modifican la geometría existente requieren una selección actual y un contexto de entidad; invocar una fábrica sin esas dependencias es insuficiente para una edición útil.

Mallado y verificación

Para sólidos con un recuento de vértices estimado superior a 50,000 y compatibilidad con el trabajador del navegador, el visor pone en cola la construcción de malla en un trabajador del módulo. Los sólidos más pequeños se entrelazan sincrónicamente. La cola de malla maneja la finalización, los trabajos obsoletos, los errores de los trabajadores y la limpieza. El umbral es una estimación utilizada para la programación, no un límite de tamaño de modelo documentado.

Comprobaciones lógicas de la ventana gráfica, desde la raíz del repositorio
bun test apps/desktop/src/viewport
bun run --filter @cadcamfun/desktop typecheck

Las pruebas lógicas cubren ayudas de renderizado, gestos de herramientas, indexación espacial, reproducción y superposiciones. El comportamiento del navegador/WebGL también depende del entorno gráfico; Inspeccione la interacción real de la ventana gráfica al cambiar los controles de la cámara, el ciclo de vida de la escena o el renderizado.

Ejemplo de reproducción controlada

Un padre puede poseer controles de transporte sin duplicar la línea de tiempo de movimiento del espectador. Este componente acepta un programa CAM ya construido y controla el tiempo, el estado de reproducción, la velocidad y el ajuste preestablecido de la ventana gráfica. Sus rutas de importación asumen un archivo directamente debajo apps/desktop/src.

Vista previa del programa con controles de transporte externos.
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>
}

El generador de reproducción comienza en el origen, expande los ciclos en movimientos y calcula la duración a partir de la duración del viaje y la alimentación. Su velocidad rápida predeterminada es 5,000 mm/min y la tolerancia de teselación de arco predeterminada es 0.1 mm. Estas son suposiciones preliminares, no aceleración medida de la máquina ni sincronización del controlador. Los comandos de permanencia conservan los segundos indicados; Los comentarios y las entradas de solo orientación no agregan recorrido lineal.

Los colores de las herramientas se asignan según la primera aparición de cada identificador de herramienta y se conservan en todas sus rutas. Proporcionar un mapa de herramientas/herramienta predeterminada para la geometría de ensamblaje; una ruta coloreada por sí sola no establece las dimensiones del cortador o del soporte utilizadas en la verificación.

Edición de recetas y límites de herramientas actuales

OperaciónGesto y condiciones previasComportamiento actual
CompensarSeleccione una entidad compatible y luego arrastre; En su lugar, Shift elige la entidad debajo del cursor.Las líneas/polilíneas/rectángulos producen un resultado de polilínea. Las implementaciones de círculos y arcos trasladan el centro manteniendo el radio; Esta herramienta no es una operación general de compensación concéntrica para curvas.
Recortar/extenderPrimero seleccione las entidades de origen y de límite, active Recortar y haga clic en el destino. Alt selecciona el modo extendido.La implementación busca intersecciones en las otras entidades seleccionadas. Cambia líneas y polilíneas; los tipos de objetivos no admitidos o las intersecciones faltantes no producen ninguna edición.
Filete/chaflánElige dos líneas que se crucen. Shift cambia a chaflán.La herramienta compartida utiliza un radio inicial de 5 mm y reemplaza el par con líneas recortadas y una polilínea de conexión. No es un filete arbitrario de borde sólido.
Transformar un sólidoProporcionar onTransformCommit, seleccione una malla y luego active traducir/rotar/escalar.La devolución de llamada informa el índice sólido y los valores de transformación. La selección y transformación de artilugios están desactivados en el modo de cuatro vistas.

Estos detalles provienen de las implementaciones de gestos más que de las etiquetas de su paleta. Inspeccione la vista previa antes de confirmar y use Deshacer si el resultado difiere de la geometría deseada. Una herramienta que no devuelve ningún comando puede significar que sus prerrequisitos geométricos no se cumplieron, no que el editor haya perdido el evento del puntero.

Fallos de renderizado y mallado

La cola de malla en segundo plano admite como máximo 128 trabajos pendientes de forma predeterminada, se ejecuta uno a la vez y tiene un tiempo de espera predeterminado de 15 segundos por trabajo. Restablecer una escena finaliza al trabajador y borra el trabajo en cola; las respuestas obsoletas se ignoran. Las respuestas de los trabajadores no válidas, los errores de decodificación de mensajes, los tiempos de espera y las fallas de capacidad de la cola informan errores a través de la devolución de llamada de la cola.

SíntomaAcción
Lienzo vacío sin geometría.Asigne al padre un tamaño distinto de cero, verifique la visibilidad de la entidad/capa y ajuste la vista.
No se puede seleccionar nadaVerifique los bloqueos de entidad/capa en 2D; verifique el modo de cuatro vistas y transforme el estado en 3D.
Tiempo de espera de malla o cola llenaReduzca la complejidad de la escena o la cantidad de sólidos enviados simultáneamente e inspeccione el error del trabajador. Un lote fallido se borra en lugar de instalarse parcialmente como un trabajo completado.
El tiempo de reproducción parece incorrectoVerifique las transmisiones del programa, los movimientos de permanencia, las suposiciones de velocidad rápida y si un programa modificado restablece el tiempo de los padres.
WebGL no está disponibleUtilice un entorno de gráficos compatible e inspeccione el estado del renderizador no disponible del componente; Las pruebas lógicas no pueden probar la disponibilidad de la GPU.

Las pruebas relevantes incluyen editor2d/tools/offset.test.ts, annotation-transform.test.ts, spatial/grid.test.ts, view3d/playback.test.ts, y toolpath-overlays.test.ts. La implementación de la cola de malla es view3d/mesh-jobs.ts.

Unidades de exposición en detalle

El editor siempre trabaja en milímetros. Solo se convierte lo que el usuario lee y escribe, utilizando los factores exactos que se indican a continuación. La unidad propia de un dibujo almacenado permanece mm o inch; las unidades adicionales son opciones de visualización únicamente.

UnidadEtiquetamm por unidadDecimales predeterminadosUnidad de programa de código G
mmmilímetros13milímetros
umµm0.0011milímetros
cmcentímetro104milímetros
mm10006milímetros
inchpulgada25.44pulgada
thoutú0.02542pulgada
Conversión y análisis de longitudes (apps/desktop/src/viewport/units.ts)
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 elimina un sufijo alfabético final (incluido µ y °) e interpreta el número en la unidad de visualización actual. El sufijo no se utiliza para elegir una unidad, por lo que escribir 2 mm mientras que la visualización está en pulgadas produce 50.8 mm. Devoluciones de entrada vacías, no numéricas e infinitas undefined, y los editores deben mantener el valor anterior en ese caso.

2Cámara D y cuadrícula

mundo (mm, +Y arriba)pantalla (px, +Y abajo) centro+X+Y (ancho/2, alto/2)+x+y →
La cámara del editor 2D almacena el punto mundial en el centro de la ventana gráfica y una escala en píxeles por milímetro. worldToScreen voltea Y para que el mundo +Y apunte hacia arriba en la pantalla.
Constante / funciónValorComportamiento
ZOOM_STEP1.15Factor por paso de rueda; zoomAt mantiene fijo el punto mundial bajo el cursor.
MIN_SCALE / MAX_SCALE0.001 / 100,000 px per mmLa escala está sujeta a este rango.
FIT_MARGIN0.1Fracción de la ventana gráfica mantenida como margen por cameraForBounds.
createCamera()centro (0, 0), escala 1, 800 × 600Cámara inicial antes del primer cambio de tamaño.
gridStep(scale, major = 10, minPixels = 8)1-2-5 escaleraEl paso más pequeño que mantiene los puntos de la cuadrícula al menos 8 px de distancia.
Mapeo entre el mundo y la pantalla.
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

Representar elimina entidades contra visibleBounds(camera). El ajuste también evita escanear todo el dibujo: una cuadrícula espacial uniforme devuelve entidades cuyos límites se encuentran dentro de la tolerancia de ajuste más un margen candidato de 2 mm, y solo esas se pasan al núcleo. findSnap. Esto mantiene el puntero en movimiento rápido en dibujos con muchas entidades.

Referencia de ajuste

Los tipos de instantáneas se prueban en orden de prioridad. El orden predeterminado coincide con el editor heredado: endpoint, midpoint, center, intersection, perpendicular, tangent, nearest, y quadrant. Los puntos finales son los vértices de la entidad de origen, no los de su teselación.

ConfiguraciónSignificado
enabledinterruptor maestro; false desactiva todos los ajustes.
typesTipos de instantáneas habilitados, la prioridad más alta primero.
toleranceRadio de ajuste en milímetros; no depende del zoom.
gridEnabled, gridSpacingAjustar a la cuadrícula cuando no se aplica ninguna referencia a objetos.
referencePointEl punto del que se extrae. perpendicular y tangent no encontrar nada sin él.

La canalización devuelve el complemento, los ID de las entidades bajo el cursor (el más cercano primero, que consume la herramienta de selección) y el número de candidatos considerados.

Cómo se cronometra la reproducción de la trayectoria

buildPlayback(program, rapidRate = 5000, tolerance = 0.1) convierte un programa CAM en segmentos cronometrados. La duración de cada movimiento es su duración dividida por su avance (o por la velocidad rápida para los rápidos), multiplicada por 60, lo que da segundos. Las viviendas añaden su propio tiempo sin moverse. Los comentarios, movimientos de orientación y ciclos fijos no se dibujan como segmentos. Los arcos se dividen en cuerdas cuya sagitta permanece dentro tolerance (entre 2 y 65,536 cuerdas por arco), y Z se interpola a lo largo del arco para hélices.
Busca y colorea una vista previa
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.
Vista previa de reproducción Arrastrar para orbitar · desplazarse para hacer zoom · arrastrar con el botón derecho para desplazarse
El mismo programa de bolsillo que en la página CAM, reproducido en el primer color de herramienta (388bdf22). En el escritorio, cada herramienta adicional obtiene el siguiente color en la paleta: 5597316c879e, 9f15, #e#f#, #facc#, etc.
segmentIndexAt encuentra el segmento de reproducción mediante búsqueda binaria, por lo que la búsqueda es económica incluso para programas largos. Buscar más allá del final devuelve la posición final, y toolAt luego informa la última herramienta. El tiempo de reproducción es una estimación visual basada en transmisiones programadas; ignora la aceleración de la máquina, por lo que una máquina real tarda más.

Prácticas de ventana gráfica

  • Convertir en el borde: almacenar y calcular en milímetros y radianes, y formatear solo para mostrar con formatLength y formatAngle.
  • Nunca reutilice una longitud analizada después parseLength regresa undefined; mantenga el valor anterior y muestre una sugerencia de validación.
  • Al agregar una herramienta de dibujo, regístrela en la tabla de fábrica de herramientas para que la barra de herramientas, los accesos directos y las pruebas la dirijan con el mismo ID.
  • Mantenga espaciales las consultas instantáneas de candidatos. Pasando cada entidad a findSnap en cada movimiento del puntero derrota al índice.
  • Trate la duración de la reproducción como una vista previa, no como una cotización de tiempo de ciclo.

Pruebas de éxito a escala: la cuadrícula espacial

El editor 2D apunta a 60 fps con 10,000 entidades, por lo que las pruebas de acierto y la selección nunca escanean todas las entidades por evento de puntero. viewport/spatial/grid.ts mantiene una cuadrícula uniforme: cada elemento se registra en cada celda que toca su cuadro delimitador, y una consulta devuelve todos los elementos cuyos límites se cruzan con el cuadro de consulta, en orden de inserción. El resultado es exacto, nunca una muestra.

ConfiguraciónValorPor qué
Tamaño de celda predeterminado50 unidades mundiales (mm)Se adapta a un dibujo de aproximadamente 1 m de ancho
Tamaño mínimo de celda1e-6Protege contra un tamaño cero o negativo, que se repetiría para siempre
Límite de celdas por artículo4,096Los elementos más grandes (una línea larga a lo largo de la hoja) se rastrean aparte en lugar de por celda
MétodoComportamiento
build(items)Reconstruir desde cero
upsert(id, item)Insertar o reemplazar un elemento por identificación
remove(id)Eliminar; los identificadores desconocidos se ignoran
query(bounds)Identificadores cuyos límites cruzan la caja
cuadro de consultaentidad ABlarga fila

Se visitan las celdas tocadas por el cuadro de consulta discontinuo; A y la línea larga se devuelven porque sus límites la cruzan, B no.

3Cola de mallado D

Los sólidos se mallan en un Web Worker para que el subproceso de la interfaz de usuario nunca se bloquee. MeshWorkerQueue en view3d/mesh-jobs.ts ejecuta un trabajo a la vez:

ReglaValorMensaje sobre el fracaso
Capacidad (en cola + en ejecución)128La cola de malla 3D está llena. Reducir la complejidad de la escena.
Tiempo de espera por trabajo15 s3Se agotó el tiempo de espera del mallado D. Reducir la complejidad de la escena.
error del trabajador—El mensaje del trabajador, o "El trabajador de la malla se detuvo inesperadamente".
respuesta indescodificable—El trabajador de la malla no pudo decodificar su respuesta.
Mala geometríalas posiciones deben ser Float32Array, índices Uint32ArrayEl trabajador de malla devolvió una geometría no válida.

Cualquier falla finaliza al trabajador y borra toda la cola, por lo que el trabajo de escena obsoleto nunca llega después de una edición más reciente; el siguiente envío inicia un nuevo trabajador. Las respuestas coinciden con la identificación del trabajo, por lo que se ignora una respuesta tardía de un trabajador despedido.

2Implementaciones de herramientas D

ArchivoHerramientas
tools/two-point.tslínea, rectángulo, círculo por diámetro, elipse
tools/chained.tspolilínea, arco de tres puntos
tools/fillet-chamfer.tsredondear o biselar la esquina entre dos líneas
tools/offset.tsdesplazar una polilínea, rectángulo, círculo o arco por una distancia
tools/trim.tsrecortar y extender
tools/select.tshaga clic, encuadre y agregue/elimine selección
tools/annotation-transform.tsmover y transformar anotaciones

Cada herramienta es una pequeña máquina de estados con onPointerDown, onPointerMove y onPointerUp, creado por una fábrica en tools/index.ts, uno por entrada de paleta. Las posiciones del puntero pasan snap-pipeline.ts antes de que una herramienta los vea.