diff --git a/client/src/components/filamentImportModal.tsx b/client/src/components/filamentImportModal.tsx index 97ac725d5..77453483c 100644 --- a/client/src/components/filamentImportModal.tsx +++ b/client/src/components/filamentImportModal.tsx @@ -18,7 +18,14 @@ export function FilamentImportModal(props: { const filamentOptions = externalFilaments.data?.map((item) => { return { - label: formatFilamentLabel(item.name, item.diameter, item.manufacturer, item.material, item.weight), + label: formatFilamentLabel( + item.name, + item.diameter, + item.manufacturer, + item.material, + item.weight, + item.spool_type + ), value: item.id, item: item, }; diff --git a/client/src/pages/filaments/functions.ts b/client/src/pages/filaments/functions.ts index c47a7fbe1..81b397368 100644 --- a/client/src/pages/filaments/functions.ts +++ b/client/src/pages/filaments/functions.ts @@ -10,6 +10,14 @@ import { IFilament } from "./model"; export async function createFilamentFromExternal(externalFilament: ExternalFilament): Promise { const vendor = await getOrCreateVendorFromExternal(externalFilament.manufacturer); + let color_hex = undefined; + if (externalFilament.color_hex) { + color_hex = externalFilament.color_hex; + } else if (externalFilament.color_hexes && externalFilament.color_hexes.length > 0) { + // TODO: Support for multi-color filaments + color_hex = externalFilament.color_hexes[0]; + } + const body: Omit & { vendor_id: number } = { name: externalFilament.name, material: externalFilament.material, @@ -18,7 +26,7 @@ export async function createFilamentFromExternal(externalFilament: ExternalFilam diameter: externalFilament.diameter, weight: externalFilament.weight, spool_weight: externalFilament.spool_weight || undefined, - color_hex: externalFilament.color_hex, + color_hex: color_hex, settings_extruder_temp: externalFilament.extruder_temp || undefined, settings_bed_temp: externalFilament.bed_temp || undefined, external_id: externalFilament.id, diff --git a/client/src/pages/spools/functions.tsx b/client/src/pages/spools/functions.tsx index 1a8a1b8c0..fa2e309ad 100644 --- a/client/src/pages/spools/functions.tsx +++ b/client/src/pages/spools/functions.tsx @@ -3,7 +3,7 @@ import { formatLength, formatWeight } from "../../utils/parsing"; import { getAPIURL } from "../../utils/url"; import { ISpool } from "./model"; import { IFilament } from "../filaments/model"; -import { useGetExternalDBFilaments } from "../../utils/queryExternalDB"; +import { SpoolType, useGetExternalDBFilaments } from "../../utils/queryExternalDB"; import { useMemo } from "react"; export async function setSpoolArchived(spool: ISpool, archived: boolean) { @@ -28,7 +28,8 @@ export function formatFilamentLabel( diameter: number, vendorName?: string, material?: string, - weight?: number + weight?: number, + spoolType?: SpoolType ): string { const portions = []; if (vendorName) { @@ -43,6 +44,9 @@ export function formatFilamentLabel( if (weight) { extras.push(formatWeight(weight)); } + if (spoolType) { + extras.push(spoolType.charAt(0).toUpperCase() + spoolType.slice(1) + " spool"); + } return `${portions.join(" - ")} (${extras.join(", ")})`; } @@ -89,7 +93,14 @@ export function useGetFilamentSelectOptions() { const data = externalFilaments.data?.map((item) => { return { - label: formatFilamentLabel(item.name, item.diameter, item.manufacturer, item.material, item.weight), + label: formatFilamentLabel( + item.name, + item.diameter, + item.manufacturer, + item.material, + item.weight, + item.spool_type + ), value: item.id, weight: item.weight, spool_weight: item.spool_weight || undefined, diff --git a/client/src/utils/queryExternalDB.ts b/client/src/utils/queryExternalDB.ts index 96a7fd983..d873dff73 100644 --- a/client/src/utils/queryExternalDB.ts +++ b/client/src/utils/queryExternalDB.ts @@ -1,6 +1,27 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { getAPIURL } from "./url"; +export enum SpoolType { + PLASTIC = "plastic", + CARDBOARD = "cardboard", + METAL = "metal", +} + +export enum Finish { + MATTE = "matte", + GLOSSY = "glossy", +} + +export enum MultiColorDirection { + COAXIAL = "coaxial", + LONGITUDINAL = "longitudinal", +} + +export enum Pattern { + MARBLE = "marble", + SPARKLE = "sparkle", +} + export interface ExternalFilament { id: string; manufacturer: string; @@ -8,11 +29,18 @@ export interface ExternalFilament { material: string; density: number; weight: number; - spool_weight: number | null; + spool_weight?: number; + spool_type?: SpoolType; diameter: number; - color_hex: string; - extruder_temp: number | null; - bed_temp: number | null; + color_hex?: string; + color_hexes?: string[]; + extruder_temp?: number; + bed_temp?: number; + finish?: Finish; + multi_color_direction?: MultiColorDirection; + pattern?: Pattern; + translucent: boolean; + glow: boolean; } export interface ExternalMaterial { diff --git a/spoolman/externaldb.py b/spoolman/externaldb.py index 1168ae05f..6fd98f02b 100644 --- a/spoolman/externaldb.py +++ b/spoolman/externaldb.py @@ -3,6 +3,7 @@ import datetime import logging import os +from enum import Enum from pathlib import Path from typing import Optional @@ -21,6 +22,27 @@ logger = logging.getLogger(__name__) +class SpoolType(Enum): + PLASTIC = "plastic" + CARDBOARD = "cardboard" + METAL = "metal" + + +class Finish(Enum): + MATTE = "matte" + GLOSSY = "glossy" + + +class MultiColorDirection(Enum): + COAXIAL = "coaxial" + LONGITUDINAL = "longitudinal" + + +class Pattern(Enum): + MARBLE = "marble" + SPARKLE = "sparkle" + + class ExternalFilament(BaseModel): id: str = Field(description="A unique ID for this filament.", example="polymaker_pla_polysonicblack_1000_175") manufacturer: str = Field(description="Filament manufacturer.", example="Polymaker") @@ -29,10 +51,29 @@ class ExternalFilament(BaseModel): density: float = Field(description="Density in g/cm3.", example=1.23) weight: float = Field(description="Net weight of a single spool.", example=1000) spool_weight: Optional[float] = Field(default=None, description="Weight of an empty spool.", example=140) + spool_type: Optional[SpoolType] = Field(description="Type of spool.", example=SpoolType.PLASTIC) diameter: float = Field(description="Filament in mm.", example=1.75) - color_hex: str = Field(description="Filament color code in hex format.", example="2c3232") + color_hex: Optional[str] = Field( + default=None, + description="Filament color code in hex format, for single-color filaments.", + example="2c3232", + ) + color_hexes: Optional[list[str]] = Field( + default=None, + description="For multi-color filaments. List of hex color codes in hex format.", + example=["2c3232", "5f5f5f"], + ) extruder_temp: Optional[int] = Field(default=None, description="Extruder/nozzle temperature in °C.", example=210) bed_temp: Optional[int] = Field(default=None, description="Bed temperature in °C.", example=50) + finish: Optional[Finish] = Field(default=None, description="Finish of the filament.", example=Finish.MATTE) + multi_color_direction: Optional[MultiColorDirection] = Field( + default=None, + description="Direction of multi-color filaments.", + example=MultiColorDirection.COAXIAL, + ) + pattern: Optional[Pattern] = Field(default=None, description="Pattern of the filament.", example=Pattern.MARBLE) + translucent: bool = Field(default=False, description="Whether the filament is translucent.") + glow: bool = Field(default=False, description="Whether the filament is glow-in-the-dark.") class ExternalFilamentsFile(BaseModel):