332 lines
12 KiB
TypeScript
332 lines
12 KiB
TypeScript
// Типы API между страницами и сервером.
|
||
|
||
/** Файл в папках ComfyUI (как в ответах ComfyUI и параметрах /view). */
|
||
export interface FileRef {
|
||
filename: string;
|
||
subfolder: string;
|
||
type: string; // 'input' | 'output' | 'temp'
|
||
}
|
||
|
||
export interface ApiError {
|
||
error: string;
|
||
}
|
||
|
||
// ---------- батчи картинок (ImageBatches + источники + Images) ----------
|
||
/** Пользовательский ввод text2img (ImageBatchTextSources) — всё, что нужно, чтобы повторить запуск. */
|
||
export interface Text2ImgInput {
|
||
shape: string;
|
||
colors: string;
|
||
/** Шаблон как его ввёл пользователь: {a} — форма, {b} — цвета. Пусто — шаблон по умолчанию. */
|
||
template: string;
|
||
negative: string;
|
||
/** Картинок в батче. */
|
||
batch: number;
|
||
/** Как введено: пусто — случайный при каждом запуске. */
|
||
seed: string;
|
||
}
|
||
|
||
/**
|
||
* draft — можно править и запускать; pending — в работе; done / error — завершён.
|
||
* Батч с картинками, в работе или из загрузки заблокирован: text-батч можно только продублировать.
|
||
*/
|
||
export type BatchState = 'draft' | 'pending' | 'done' | 'error';
|
||
|
||
/** Картинка батча (Images): id и проект, если из неё создан проект. */
|
||
export interface BatchImage extends FileRef {
|
||
id: number;
|
||
projectId: number | null;
|
||
}
|
||
|
||
/** Проект — работа над одной картинкой из батча. */
|
||
export interface Project {
|
||
id: number;
|
||
created: number;
|
||
/** батч, из которого картинка */
|
||
batchId: number;
|
||
/** откуда исходная картинка: сгенерирована (text — SDXL) или загружена */
|
||
imageSource: 'text' | 'upload';
|
||
/** исходная картинка */
|
||
image: BatchImage;
|
||
/** последняя очищенная картинка (история очисток не хранится) */
|
||
clean: FileRef | null;
|
||
cleanUpdated: number | null;
|
||
/** идёт очистка: prompt_id в ComfyUI */
|
||
cleanJobId: string | null;
|
||
/** ошибка последней очистки */
|
||
cleanError?: string;
|
||
/** положение идущей очистки в очереди ComfyUI */
|
||
live?: LiveStatus;
|
||
/**
|
||
* 3D-модель без текстур (история не хранится). Генерирует её Hunyuan3D-2 mini или TRELLIS.2;
|
||
* TRELLIS.2 заодно заполняет и texture.
|
||
*/
|
||
model: ModelArtifacts | null;
|
||
/** идёт генерация модели: prompt_id в ComfyUI */
|
||
modelJobId: string | null;
|
||
modelError?: string;
|
||
/** положение идущей генерации в очереди ComfyUI */
|
||
modelLive?: LiveStatus;
|
||
/** текстурированная модель и её текстуры (от TRELLIS.2 или Hunyuan3D-2 Paint) */
|
||
texture: TextureArtifacts | null;
|
||
/** идёт текстурирование (Paint): prompt_id в ComfyUI */
|
||
textureJobId: string | null;
|
||
textureError?: string;
|
||
textureLive?: LiveStatus;
|
||
}
|
||
|
||
/** Чем сгенерирована 3D-модель. */
|
||
export type ModelGenerator = 'hunyuan' | 'trellis';
|
||
|
||
export const GENERATOR_NAMES: Record<ModelGenerator, string> = { hunyuan: 'Hunyuan3D-2 mini', trellis: 'TRELLIS.2' };
|
||
|
||
/** Модель без текстур. */
|
||
export interface ModelArtifacts {
|
||
generator: ModelGenerator;
|
||
glb: FileRef;
|
||
/** PNG-превью (рендер без текстур) */
|
||
preview: FileRef | null;
|
||
/** число треугольников в GLB */
|
||
faces: number | null;
|
||
/** мс */
|
||
updated: number;
|
||
}
|
||
|
||
/** Откуда текстуры: вместе с моделью от TRELLIS.2 или отдельным текстурированием Hunyuan3D-2 Paint. */
|
||
export type TextureSource = 'trellis' | 'paint';
|
||
|
||
/** Текстурированная модель и всё, что к ней относится; каких-то файлов может не быть (у Paint — metallic, roughness). */
|
||
export interface TextureArtifacts {
|
||
source: TextureSource;
|
||
/** текстурированная модель */
|
||
glb: FileRef | null;
|
||
faces: number | null;
|
||
baseColor: FileRef | null;
|
||
/** металличность (канал B карты metallicRoughness glTF) в оттенках серого */
|
||
metallic: FileRef | null;
|
||
/** шероховатость (канал G карты metallicRoughness glTF) в оттенках серого */
|
||
roughness: FileRef | null;
|
||
/** изображение UV-развёртки */
|
||
uv: FileRef | null;
|
||
/** виды: у TRELLIS.2 — рендеры модели с 4 сторон, у Paint — 6 видов, нарисованных моделью */
|
||
views: FileRef[];
|
||
/** мс */
|
||
updated: number;
|
||
}
|
||
|
||
/** Генерация 3D-модели проекта. */
|
||
export interface ProjectModelRequest {
|
||
generator: ModelGenerator;
|
||
/** Пусто — случайный. */
|
||
seed: number | string;
|
||
/** Hunyuan3D-2 mini */
|
||
steps: number | string;
|
||
octree: number | string;
|
||
/** целевое число треугольников после упрощения */
|
||
faces: number | string;
|
||
/** TRELLIS.2: размер текстуры, px */
|
||
textureSize: number | string;
|
||
/** TRELLIS.2: металличность и шероховатость (карты metallic, roughness) в модели */
|
||
pbr: boolean;
|
||
}
|
||
|
||
/** Текстурирование модели проекта (Hunyuan3D-2 Paint). */
|
||
export interface ProjectTextureRequest {
|
||
/** Пусто — случайный. */
|
||
seed: number | string;
|
||
/** размер текстуры, px */
|
||
textureSize: number | string;
|
||
/** снимать блики и тени с картинки (Hunyuan3D Delight) */
|
||
delight: boolean;
|
||
}
|
||
|
||
interface BatchBase {
|
||
id: number;
|
||
created: number;
|
||
updated: number;
|
||
/** ImageBatchTextSources.id или ImageBatchUploadSources.id — по sourceType */
|
||
sourceId: number;
|
||
state: BatchState;
|
||
error?: string;
|
||
/** Из какого батча продублирован. */
|
||
clonedFrom: number | null;
|
||
/** Картинки батча (Images.batchId). */
|
||
images: BatchImage[];
|
||
live?: LiveStatus;
|
||
}
|
||
|
||
export interface TextBatch extends BatchBase {
|
||
sourceType: 'text';
|
||
source: { id: number; input: Text2ImgInput };
|
||
/** prompt_id последнего запуска в ComfyUI. */
|
||
jobId: string | null;
|
||
/** Фактический seed последнего запуска. */
|
||
seedUsed: number | null;
|
||
/** Итоговый позитивный промпт последнего запуска. */
|
||
prompt: string;
|
||
}
|
||
|
||
export interface UploadBatch extends BatchBase {
|
||
sourceType: 'upload';
|
||
/** Исходные имена загруженных файлов. */
|
||
source: { id: number; files: string[] };
|
||
}
|
||
|
||
export type ImageBatch = TextBatch | UploadBatch;
|
||
|
||
/** В батче есть картинка, из которой создан проект. */
|
||
export function hasProject(b: ImageBatch): boolean {
|
||
return b.images.some(i => i.projectId != null);
|
||
}
|
||
|
||
export function isLocked(b: ImageBatch): boolean {
|
||
return b.sourceType === 'upload' || b.state === 'pending' || b.images.length > 0;
|
||
}
|
||
|
||
// ---------- запросы на запуск ----------
|
||
/** Очистка исходника проекта. */
|
||
export interface CleanupRequest {
|
||
size: number | string;
|
||
/** Отступ от объекта до края кадра, px с каждой стороны. */
|
||
margin: number | string;
|
||
grow: number | string;
|
||
background: string;
|
||
}
|
||
|
||
// ---------- задачи ComfyUI (таблица jobs; отслеживаются трекером) ----------
|
||
export type JobType = 'text2img' | 'cleanup' | 'model' | 'texture';
|
||
export type JobState = 'pending' | 'done' | 'error';
|
||
|
||
/** Состояние незавершённой задачи в очереди ComfyUI (не хранится, считается сервером на лету). */
|
||
export type LiveStatus = { state: 'queued'; position: number } | { state: 'running' };
|
||
|
||
export interface Text2ImgParams {
|
||
/** батч (ImageBatches.id), к которому прикрепляются картинки */
|
||
batchId: number;
|
||
shape: string;
|
||
colors: string;
|
||
template: string;
|
||
negative: string;
|
||
batch: number;
|
||
seed: number;
|
||
/** Итоговый позитивный промпт, как его увидит модель. */
|
||
prompt: string;
|
||
}
|
||
|
||
export interface CleanupParams {
|
||
/** проект, к которому прикрепляется результат */
|
||
projectId: number;
|
||
size: number;
|
||
margin: number;
|
||
grow: number;
|
||
background: string;
|
||
}
|
||
|
||
export interface ModelParams {
|
||
/** проект, к которому прикрепляется модель */
|
||
projectId: number;
|
||
generator: ModelGenerator;
|
||
seed: number;
|
||
faces: number;
|
||
/** Hunyuan3D-2 mini */
|
||
steps?: number;
|
||
octree?: number;
|
||
/** TRELLIS.2 */
|
||
textureSize?: number;
|
||
pbr?: boolean;
|
||
}
|
||
|
||
export interface TextureParams {
|
||
/** проект, к которому прикрепляется результат */
|
||
projectId: number;
|
||
seed: number;
|
||
textureSize: number;
|
||
delight: boolean;
|
||
}
|
||
|
||
interface JobOf<T extends JobType, P> {
|
||
/** prompt_id в ComfyUI */
|
||
id: string;
|
||
type: T;
|
||
/** мс с эпохи */
|
||
created: number;
|
||
state: JobState;
|
||
error?: string;
|
||
/** картинка-исходник (для cleanup и model) */
|
||
source: FileRef | null;
|
||
params: P;
|
||
/** результаты-картинки (для model — PNG-превью) */
|
||
images: FileRef[];
|
||
/** GLB-файлы (model, texture) */
|
||
models: FileRef[];
|
||
live?: LiveStatus;
|
||
}
|
||
|
||
export type Text2ImgJob = JobOf<'text2img', Text2ImgParams>;
|
||
export type CleanupJob = JobOf<'cleanup', CleanupParams>;
|
||
export type ModelJob = JobOf<'model', ModelParams>;
|
||
export type TextureJob = JobOf<'texture', TextureParams>;
|
||
export type Job = Text2ImgJob | CleanupJob | ModelJob | TextureJob;
|
||
|
||
// ---------- значения полей форм (тоже в SQLite) ----------
|
||
export interface Text2ImgSettings {
|
||
shape: string;
|
||
colors: string;
|
||
template: string;
|
||
negative: string;
|
||
batch: string;
|
||
seed: string;
|
||
promptsOpen: boolean;
|
||
}
|
||
|
||
export interface CleanupSettings {
|
||
size: string;
|
||
margin: string;
|
||
grow: string;
|
||
background: string;
|
||
}
|
||
|
||
export interface ModelSettings {
|
||
generator: ModelGenerator;
|
||
seed: string;
|
||
/** Hunyuan3D-2 mini */
|
||
steps: string;
|
||
octree: string;
|
||
faces: string;
|
||
/** TRELLIS.2 */
|
||
trellisFaces: string;
|
||
textureSize: string;
|
||
trellisPbr: boolean;
|
||
}
|
||
|
||
export interface TextureSettings {
|
||
seed: string;
|
||
textureSize: string;
|
||
delight: boolean;
|
||
}
|
||
|
||
export type SettingsByPage = {
|
||
text2img: Text2ImgSettings; cleanup: CleanupSettings; model: ModelSettings; texture: TextureSettings;
|
||
};
|
||
export type SettingsPage = keyof SettingsByPage;
|
||
|
||
// ---------- очередь ComfyUI ----------
|
||
export type JobKind = 'генерация' | 'очистка фона' | '3D-модель' | 'текстура' | 'другое';
|
||
|
||
export interface QueueItem {
|
||
id: string;
|
||
kind: JobKind;
|
||
}
|
||
|
||
export interface QueueInfo {
|
||
running: QueueItem[];
|
||
pending: QueueItem[];
|
||
}
|
||
|
||
// ---------- перенос из localStorage старой версии ----------
|
||
export interface ImportRequest {
|
||
settings: Partial<{ [P in SettingsPage]: Partial<SettingsByPage[P]> }>;
|
||
}
|
||
|
||
export const DEFAULT_TEMPLATE =
|
||
'Game character. Full body visible. Empty arms. {a}, centered on white background. {b}. Game sprite aesthetic.';
|