Перейти к содержанию
CADCAMFUN
Документы

Документация

Область просмотра

Инструменты рисования на холсте и рендеринг Three.js используют общую геометрию, сохраняя при этом явное состояние редактирования и воспроизведения.

Автоматически переведено с английского. Смотреть оригинал на английском

Компоненты видового экрана

apps/desktop/src/viewport/index.ts экспорт Editor2D, View3D, их типы опор, доступные идентификаторы инструментов и solidsFromProfiles. Оба компонента заполняют своего родителя: предоставляют контейнер с ненулевой шириной и высотой. Основные объекты САПР и программы CAM представляют собой общую модель данных.

Редактор 2D выполняет рендеринг в Canvas 2D и сохраняет собственную историю выделения, камеры и команд. Средство просмотра 3D использует Three.js, элементы управления орбитой и преобразованием, асинхронные задания сетки и программное воспроизведение. Рендеринг траектории или твердого тела не зависит от его сохранения или проверки производственной операции.

Интеграционный договор

Editor2DProps требует drawing, onChange, и selectedTool. Подайте созданные рисунки обратно в реквизит. Компонент распознает собственные созданные объекты документа; замена документа извне загружает новый рисунок и сбрасывает состояние редактора.

Управляемый редактор 2D
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()} />

Выбор исключает заблокированные объекты и объекты на заблокированных слоях. Невидимые объекты и скрытые слои исключаются из отображаемого пространственного индекса. Новые объекты получают уникальные для документа идентификаторы и назначаются видимому, разблокированному слою, когда он доступен.

Инструменты рисования и жесты

В реестре инструментов есть фабрики для выбора, линии, прямоугольника, круга, эллипса, полилинии, дуги, текста, размеров, перемещения, поворота, масштабирования, зеркального отражения, смещения, обрезки и скругления. AVAILABLE_TOOLS производится на этих зарегистрированных заводах. startTool дополнительно признает chamfer через фабрику инструментов для скругления, но фаска не объявляется в этом массиве. Потребители должны использовать реальный реестр, чтобы решить, какие инструменты включить.

  • Масштабирование колесиком или щипком; Перетаскивание пробелом, среднее перетаскивание и панорамирование правой кнопкой мыши.
  • F соответствует индексированному рисунку. Удалить или Backspace удаляет разблокированный выбор.
  • Cmd/Ctrl+Z отменяет; Cmd/Ctrl+Shift+Z или Cmd/Ctrl+Y переделывает.
  • Enter фиксирует ломаную линию. Escape доставляется активному инструменту для отмены текущего жеста.
  • Когда текст активен, перед размещением введите символы или клавишу Backspace; исходный текст Text.

Позиции указателей преобразуются в мировые координаты перед отправкой инструмента. Привязка объединяет пространственный индекс, геометрические кандидаты и сетку, зависящую от камеры; допуск попадания при выборе соответствует восьми пикселям экрана. Машины-инструменты создают команды и предварительный просмотр, а не пишут файлы или вызывают API.

3D-рендеринг и воспроизведение

View3D принимает чертежи, твердые тела, дополнительную экструзию профиля, cam.Program, размеры заготовки и определения инструментов. Он поддерживает предварительные настройки перспективы, сверху, снизу, спереди, сзади, слева, справа, изометрии и четырех видов. Режимы отображения: затенение, затенение с краями, каркасный и рентгеновский. Освещение, свойства материала, секции обрезки, сетка, оси и начало координат настраиваются с помощью реквизита.

Управляйте воспроизведением с помощью playing, playbackTime в секундах, playbackRate, и onPlaybackTimeChange. Воспроизведение расширяет циклы сверления, мозаично формирует круговые/спиральные движения, сохраняет время задержки и отчетливо отображает быстрые движения. Карты инструментов и дополнительная геометрия фрезы, хвостовика и державки по умолчанию; предполагаемая геометрия визуально выделяется.

Обратные вызовы выбора сообщают о надежном индексе. Элементы управления преобразованием определяют положение, вращение и масштабирование. onTransformCommit; вызывающие стороны решают, как сохранить это преобразование. Наложения траектории инструмента могут отображать точки и метки, фильтры типов точек, центры дуг, радиусы дуг и прозрачность заготовки.

Воспроизведение — это визуальное представление

Зритель анимирует предоставленную программу и рисует инвентарь и инструменты. Он не выполняет удаление материала. К модулям проверки CAM относятся проверки столкновений и машинных границ; просмотр программы не означает одобрения машины.

Координаты и единицы

Координаты чертежа сердцевины и размеры заготовки указаны в миллиметрах. Углы рисования и компоненты вращения Three.js используют радианы; не применяйте это соглашение к значениям поворотной оси CAM или входным параметрам, которые явно используют градусы. viewport/units.ts содержит помощники преобразования отображаемых миллиметров и дюймов. Преобразуйте границы ввода/вывода, чтобы привязка, геометрия и движение траектории инструмента сохраняли согласованную систему единиц.

Камера 2D отображает мировые координаты в пикселях CSS; Размеры холста подложки включают соотношение пикселей устройства. При изменении размера обновляется камера и резервный буфер. ResizeObserver. Масштаб камеры определяет шаг сетки и допуски попадания в экранное пространство.

Дюймовый дисплей преобразуется ровно с точностью 25.4 мм на дюйм, а длины по умолчанию равны 3 десятичным знакам (apps/desktop/src/viewport/units.ts). В редакторе 2D каждый шаг колеса масштабируется с коэффициентом 1.15, масштаб фиксируется между 0.001 и 100,000, а при показе по размеру остается запас 10 % (editor2d/camera.ts).

Ресурсы и жизненный цикл

Компонент 2D отменяет поставленные в очередь кадры анимации и отключает наблюдатель изменения размера при размонтировании. Компонент 3D реализует прослушиватели изменения размера и видимости, элементы управления орбитой и преобразованием, рабочие сетки, планирование анимации, геометрию, материалы, спрайты, сетки инструментов и средство рендеринга WebGL.

Планировщик кадров объединяет недействительности и запрашивает дополнительные кадры, когда они необходимы для демпфирования камеры или воспроизведения. Изменения видимости приостанавливают работу. Это политика планирования, а не гарантированный бюджет частоты кадров для каждой модели и устройства.

Карта модуля

  • editor2d/editor2d.tsx: управляемый компонент, отправка указателя, камера, выбор, история и рисование на холсте.
  • editor2d/tools/: машины состояний жестов и построение команд.
  • editor2d/camera.ts, render.ts, и snap-pipeline.ts: преобразования координат, рендеринг объектов, выбор и оркестровка привязок.
  • spatial/grid.ts: рисование пространственного индекса.
  • view3d/view3d.tsx: композиция сцены, элементы управления камерой, выбор, преобразования, инвентарь и инструменты.
  • view3d/playback.ts, toolpath-overlays.ts, и modeling.ts: временная шкала движения, наложение данных и преобразование профиля в твердое тело.
  • view3d/mesh-jobs.ts и mesh-worker.ts: построение фоновой геометрии и владение заданиями.

Доступность инструмента

ToolId описывает более широкий словарь инструментов; AVAILABLE_TOOLS описывает зарегистрированное подмножество. Для интерактивных инструментов используйте startTool(id, lookup, context, text). Поиск выбора запрашивает объекты-кандидаты; контекст предоставляет текущий выбор и доступ к объекту; text предоставляет содержимое аннотации.

Пропавшая фабрика возвращается undefined. Обработайте это явно, а не представляйте отключенный или нереализованный инструмент как активный режим редактирования. Инструменты, изменяющие существующую геометрию, требуют текущего выделения и контекста объекта; вызова фабрики без этих зависимостей недостаточно для полезного редактирования.

Создание сетки и проверка

Для тел с предполагаемым количеством вершин выше 50,000 и поддержкой Worker браузера средство просмотра ставит построение сетки в очередь в Worker модуля. Меньшие твердые тела сцепляются синхронно. Сетчатая очередь обрабатывает завершение, устаревшие задания, ошибки рабочих процессов и очистку. Порог — это оценка, используемая для планирования, а не документированный предел размера модели.

Проверка логики области просмотра из корня репозитория
bun test apps/desktop/src/viewport
bun run --filter @cadcamfun/desktop typecheck

Логические тесты охватывают помощники рендеринга, жесты инструментов, пространственную индексацию, воспроизведение и наложения. Поведение браузера/WebGL также зависит от графической среды; проверяйте фактическое взаимодействие области просмотра при изменении элементов управления камерой, жизненного цикла сцены или рендеринга.

Пример контролируемого воспроизведения

Родитель может владеть элементами управления транспортировкой, не дублируя временную шкалу движения зрителя. Этот компонент принимает уже созданную CAM-программу и управляет временем, состоянием воспроизведения, скоростью и предустановкой области просмотра. Его пути импорта предполагают, что файл находится непосредственно под 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>
}

Построитель воспроизведения начинает с начала координат, разбивает циклы на ходы и вычисляет длительность на основе длины перемещения и подачи. Его быстрая скорость по умолчанию составляет 5,000 мм/мин, а допуск тесселяции дуги по умолчанию составляет 0,1 мм. Это предварительные предположения, а не измеренное ускорение машины или синхронизация контроллера. Команды Dwell сохраняют установленные секунды; комментарии и записи, предназначенные только для ориентации, не добавляют линейного перемещения.

Цвета инструментов назначаются при первом появлении каждого идентификатора инструмента и сохраняются на всех его путях. Предоставление карты инструментов/инструмента по умолчанию для геометрии сборки; Цветная траектория сама по себе не определяет размеры фрезы или держателя, использованные при проверке.

Редактирование рецептов и текущих ограничений инструмента

ОперацияЖест и предварительные условияТекущее поведение
КомпенсироватьВыберите поддерживаемый объект, затем перетащите; Вместо этого Shift выбирает объект под курсором.Линии/полилинии/прямоугольники дают результат полилинии. Реализации круга и дуги перемещают центр, сохраняя при этом радиус; этот инструмент не является общей операцией концентрического смещения кривых.
Обрезать/удлинитьСначала выберите исходные и граничные объекты, активируйте «Обрезать» и щелкните цель. Alt выбирает режим расширения.Реализация ищет пересечения в других выбранных объектах. Он меняет линии и полилинии; неподдерживаемые типы целей или отсутствующие пересечения не производят редактирования.
Скругление/фаскаВыберите две пересекающиеся линии. Shift переключается на фаску.Общий инструмент использует начальный радиус 5 мм и заменяет пару обрезанными линиями и соединительной полилинией. Это не произвольное скругление со сплошной кромкой.
Преобразование твердого телаПредоставлять onTransformCommit, выберите сетку, затем активируйте перемещение/поворот/масштабирование.Обратный вызов сообщает твердый индекс и значения преобразования. Инструменты выбора и преобразования отключены в режиме четырех представлений.

Эти детали взяты из реализации жестов, а не из меток их палитры. Проверьте предварительный просмотр перед фиксацией и используйте «Отменить», если результат отличается от предполагаемой геометрии. Инструмент, не возвращающий команду, может означать, что его геометрические предпосылки не были выполнены, а не то, что редактор потерял событие указателя.

Сбои рендеринга и создания сетки

Очередь фоновой сетки по умолчанию допускает не более 128 ожидающих заданий, запускается по одному и имеет по умолчанию время ожидания в 15 секунды для каждого задания. Сброс сцены завершает работу работника и очищает работу в очереди; устаревшие ответы игнорируются. Неправильные ответы работника, ошибки декодирования сообщений, тайм-ауты и сбои емкости очереди сообщают об ошибках через обратный вызов очереди.

СимптомДействие
Пустой холст без геометрии.Присвойте родительскому элементу ненулевой размер, проверьте видимость объекта/слоя и подгоните представление.
Ничего нельзя выбратьПроверьте блокировки объектов/слоев в 2D; проверьте режим четырех представлений и состояние преобразования в 3D.
Тайм-аут сетки или полная очередьУменьшите сложность сцены или количество одновременно отправляемых тел и проверьте рабочую ошибку. Неудавшийся пакет удаляется, а не устанавливается частично как завершенное задание.
Время воспроизведения кажется неправильнымПроверьте подачу программы, ходы задержки, предположения о высокой скорости и проверьте, не сбрасывает ли измененная программа родительское время.
WebGL недоступенИспользуйте поддерживаемую графическую среду и проверьте состояние недоступности средства рендеринга компонента; логические тесты не могут доказать доступность графического процессора.

Соответствующие тесты включают в себя editor2d/tools/offset.test.ts, annotation-transform.test.ts, spatial/grid.test.ts, view3d/playback.test.ts, и toolpath-overlays.test.ts. Реализация сетчатой очереди view3d/mesh-jobs.ts.

Подробное описание единиц отображения

Редактор всегда работает в миллиметрах. Преобразовывается только то, что пользователь читает и печатает, с использованием точных коэффициентов, указанных ниже. Собственная единица сохраненного чертежа остается mm или inch; дополнительные единицы доступны только для отображения.

ЕдиницаЭтикеткамм на единицуДесятичные дроби по умолчаниюПрограммный блок G-кода
mmмм13мм
umµm0.0011мм
cmсм104мм
mm10006мм
inchдюйм25.44дюйм
thouthou0.02542дюйм
Преобразование и анализ длины (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 удаляет конечный буквенный суффикс (включая µ и °) и интерпретирует число в текущей единице отображения. Суффикс не используется для выбора юнита, поэтому введите 2 mm при отображении в дюймах получается 50.8 мм. Пустые, нечисловые и бесконечные входные данные возвращаются. undefined, и в этом случае редакторы должны сохранить предыдущее значение.

2D-камера и сетка

мир (мм, +Y вверх)экран (пикселей, +Y вниз) центр+X+Y (ширина/2, высота/2)+x+y →
Камера редактора 2D сохраняет точку мира в центре области просмотра и масштаб в пикселях на миллиметр. worldToScreen переворачивает Y так, чтобы мир +Y указывал вверх на экране.
Константа/функцияЦенитьПоведение
ZOOM_STEP1.15Коэффициент на шаг колеса; zoomAt сохраняет фиксированную точку мира под курсором.
MIN_SCALE / MAX_SCALE0.001 / 100,000 пикселей на ммМасштаб ограничен этим диапазоном.
FIT_MARGIN0.1Часть области просмотра, сохраняемая в качестве поля cameraForBounds.
createCamera()центр (0, 0), масштаб 1, 800 × 600Исходная камера до первого изменения размера.
gridStep(scale, major = 10, minPixels = 8)1-2-5 лестницаНаименьший шаг, при котором точки сетки располагаются на расстоянии не менее 8 пикселя.
Сопоставление мира и экрана
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

Рендеринг отбраковки объектов против visibleBounds(camera). Привязка также позволяет избежать сканирования всего чертежа: однородная пространственная сетка возвращает объекты, границы которых находятся в пределах допуска привязки плюс допустимый запас 2 мм, и только они передаются в ядро. findSnap. Это обеспечивает быстрое перемещение указателя на рисунках со многими объектами.

Привязка ссылки

Типы привязок проверяются в порядке приоритета. Порядок по умолчанию соответствует устаревшему редактору: endpoint, midpoint, center, intersection, perpendicular, tangent, nearest, и quadrant. Конечные точки — это вершины исходного объекта, а не его тесселяции.

ПараметрЗначение
enabledГлавный переключатель; false отключает все привязки.
typesВключенные типы привязки, сначала наивысший приоритет.
toleranceРадиус привязки в миллиметрах; это не зависит от зума.
gridEnabled, gridSpacingПривязка к сетке, когда объектная привязка не применяется.
referencePointТочка, из которой сделан вывод. perpendicular и tangent без него ничего не найти.

Конвейер возвращает снимок, идентификаторы объектов под курсором (ближайшие первыми, которые использует инструмент выбора) и количество рассматриваемых кандидатов.

Как синхронизируется воспроизведение траектории

buildPlayback(program, rapidRate = 5000, tolerance = 0.1) преобразует программу CAM в временные сегменты. Продолжительность каждого движения равна его длине, разделенной на подачу (или на быструю скорость для порогов), умноженную на 60, что дает секунды. Жители добавляют свое время, не двигаясь. Комментарии, перемещения ориентации и постоянные циклы не отображаются как сегменты. Дуги делятся на хорды, сагитта которых остается внутри. tolerance (между 2 и 65, 536 хорд на дугу), а Z интерполируется вдоль дуги для спиралей.
Найдите и раскрасьте предварительный просмотр
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.
Предварительный просмотр воспроизведения Перетащите на орбиту · прокрутите, чтобы увеличить · перетащите вправо, чтобы панорамировать
Та же самая карманная программа, что и на странице CAM, воспроизведенная в первом цвете инструмента (388bdf22). На рабочем столе каждый дополнительный инструмент получает следующий цвет в палитре: 5597316c879e, 9f15, #e#f#, #facc# и т. д.
segmentIndexAt находит воспроизводимый сегмент с помощью двоичного поиска, поэтому поиск не требует больших затрат даже для длинных программ. Поиск за концом возвращает конечную позицию, и toolAt затем сообщает последний инструмент. Время воспроизведения представляет собой визуальную оценку, основанную на запрограммированных каналах; он игнорирует ускорение машины, поэтому реальной машине требуется больше времени.

Практика видового экрана

  • Конвертируйте на краю: сохраняйте и вычисляйте в миллиметрах и радианах и форматируйте только для отображения с помощью formatLength и formatAngle.
  • Никогда повторно не используйте проанализированную длину после parseLength возвращает undefined; сохраните предыдущее значение и отобразите подсказку для проверки.
  • При добавлении инструмента рисования зарегистрируйте его в таблице фабрики инструментов, чтобы панель инструментов, ярлыки и тесты обращались к нему по одному и тому же идентификатору.
  • Сохраняйте пространственные запросы-кандидаты. Передача каждой сущности в findSnap при каждом перемещении указателя индекс побеждает.
  • Считайте продолжительность воспроизведения предварительным просмотром, а не цитатой времени цикла.

Хит-тестирование в масштабе: пространственная сетка

Редактор 2D нацелен на 60 кадров в секунду с объектами 10,000, поэтому проверка попадания и отбраковка никогда не сканируют каждый объект для каждого события указателя. viewport/spatial/grid.ts сохраняет однородную сетку: каждый элемент регистрируется в каждой ячейке, которой касается ограничивающая рамка, а запрос возвращает все элементы, границы которых пересекают поле запроса, в порядке вставки. Результат точный, а не образец.

ПараметрЦенитьПочему
Размер ячейки по умолчанию50 мировые единицы (мм)Подходит для рисунка размером около 1 м в поперечнике.
Минимальный размер ячейки1e-6Защищает от нулевого или отрицательного размера, который будет зацикливаться навсегда.
Лимит ячеек на элемент4,096Более крупные элементы (длинная линия поперек листа) отслеживаются отдельно, а не по ячейкам.
МетодПоведение
build(items)Восстановить с нуля
upsert(id, item)Вставить или заменить один элемент по идентификатору
remove(id)Удалять; неизвестные идентификаторы игнорируются
query(bounds)Идентификаторы, границы которых пересекают поле
окно запросасущность АBдлинная линия

Ячейки, затронутые пунктирным полем запроса, посещаются; A и длинная линия возвращаются, поскольку их границы пересекают ее, а B — нет.

3Очередь D-сетки

Твердые тела объединяются в веб-воркере, поэтому поток пользовательского интерфейса никогда не блокируется. MeshWorkerQueue в view3d/mesh-jobs.ts запускает одно задание за раз:

ПравилоЦенитьСообщение о неудаче
Емкость (в очереди + работа)128Очередь 3D-сетки заполнена. Уменьшите сложность сцены.
Тайм-аут на задание15 s3Время создания D-сетки истекло. Уменьшите сложность сцены.
Ошибка работника—Сообщение рабочего, или «Рабочая сетка неожиданно остановилась».
Нерасшифрованный ответ—Mesh Worker не смог расшифровать свой ответ.
Плохая геометрияпозиции должны быть Float32Array, индексы Uint32ArrayСетчатый рабочий вернул неверную геометрию.

Любой сбой завершает работу работника и очищает всю очередь, поэтому устаревшая работа сцены никогда не сохраняется после нового редактирования; следующее представление запускает нового работника. Ответы сопоставляются по идентификатору задания, поэтому поздний ответ от уволенного работника игнорируется.

2Реализации инструмента D

ФайлИнструменты
tools/two-point.tsлиния, прямоугольник, круг по диаметру, эллипс
tools/chained.tsполилиния, трехточечная дуга
tools/fillet-chamfer.tsзакруглите или скосите угол между двумя линиями
tools/offset.tsсместить полилинию, прямоугольник, круг или дугу на расстояние
tools/trim.tsобрезать и расширить
tools/select.tsщелкните, установите флажок и добавьте/удалит выделение
tools/annotation-transform.tsперемещать и трансформировать аннотации

Каждый инструмент представляет собой небольшой конечный автомат с onPointerDown, onPointerMove и onPointerUp, созданный на заводе в tools/index.ts, по одному на запись палитры. Позиции указателя проходят через snap-pipeline.ts прежде чем инструмент их увидит.