Proměňte zdrojovou fotografii na vícebarevnou, 3D tisknutelnou pixel-artovou
fidget desku ve dvou fázích: prototyp převede vaši fotografii na
pixel-artový obrázek, poté sestavení namapuje tento obrázek na mřížku
16×16 nebo 32×32 a promění každý pixel v zapadající čtvercový nebo
hexagonální díl, dodaný jako jediný soubor 3MF, jehož objekty nesou své
barvy, takže multifilamentový slicer vytiskne každý díl ve správné barvě.
Obě fáze jsou propojeny přes input_task_id.
POST /openapi/creative-lab/fidget-pixel/v1/prototype
POST /openapi/creative-lab/fidget-pixel/v1/build
Oba POST endpointy vyžadují placený plán předplatného. Požadavky z účtů
s bezplatným plánem jsou odmítnuty s 402 Payment Required.
Vygeneruje jeden pixel-artový obrázek ze zdrojové fotografie. Vrácené ID úlohy je to, co předáváte jako input_task_id koncovému bodu pro sestavení (build). Pokud výsledek není takový, jaký chcete, zavolejte tento koncový bod znovu pro další pokus — každé volání je účtováno zvlášť. Podrobnosti o tvaru odpovědi naleznete v části
Objekt úlohy prototypu Fidget Pixel.
Parametry
Name
image_url
Type
string
Povinné
Description
Zdrojová fotografie, kterou má Meshy pixelizovat. Aktuálně podporujeme formáty .jpg, .jpeg, .png a .webp.
Formát se zjišťuje dekódováním obrazových dat, nikoli podle přípony souboru v URL — URL bez přípony nebo URL, která přesměrovává, funguje, pokud se bajty dekódují na podporovaný formát. HTTP přesměrování jsou následována.
Existují dva způsoby, jak obrázek poskytnout:
Veřejně přístupná URL: URL, která je přístupná z veřejného internetu.
Data URI: Base64 kódovaná Data URI obrázku. Příklad Data URI: data:image/jpeg;base64,<vaše base64 kódovaná obrazová data>.
Name
type
Type
string
Povinné
Description
Co fotografie zobrazuje. Určuje styl pixelizace, proto volte záměrně — obě hodnoty produkují viditelně odlišné výsledky. Dostupné hodnoty:
person — subjektem je osoba (portrét nebo celá postava). Vytvoří pixelový sprite subjektu ve stylu chibi.
other — cokoliv jiného: domácí mazlíčci, předměty, maskoti, loga, krajiny. Vytvoří pixelovou ikonu subjektu ve stylu korálkové mozaiky (bead-art).
Name
name
Type
string
Description
Volitelný název úlohy pro zobrazovací účely. Maximálně 100 znaků.
Návratová hodnota
Vlastnost result v odpovědi obsahuje id úlohy nově vytvořené úlohy prototypu fidget pixel. Dotazujte se pomocí koncového bodu Získání úlohy nebo se přihlaste k odběru streamu, dokud úloha nedosáhne stavu SUCCEEDED, poté toto ID předejte koncovému bodu pro sestavení jako input_task_id.
Režimy selhání
Name
400 - Bad Request
Description
Požadavek byl nepřijatelný. Běžné příčiny:
Chybějící parametr: image_url i type jsou povinné.
Neplatný typ: type musí být person nebo other.
Neplatný formát obrázku: Poskytnuté image_url není v podporovaném formátu (.jpg, .jpeg, .png, .webp).
Rozměry obrázku mimo rozsah: Obrázek je příliš malý, přesahuje maximální velikost souboru nebo přesahuje maximální počet pixelů.
Nedostupná URL: image_url se nepodařilo stáhnout (404 nebo timeout).
Neplatná Data URI: Base64 řetězec je poškozený.
Obsah označen: Vstupní obrázek byl označen NSFW moderací.
Name
401 - Unauthorized
Description
Autentizace selhala. Zkontrolujte prosím svůj API klíč.
Name
402 - Payment Required
Description
Nedostatek kreditů k provedení této úlohy, nebo API klíč patří k účtu s bezplatným plánem.
Name
403 - Forbidden
Description
Vstupní obrázek byl označen moderací duševního vlastnictví (Content flagged for intellectual property violation). Blokovány jsou pouze Enterprise účty s povolenou filtrací duševního vlastnictví; nic není účtováno.
Name
429 - Too Many Requests
Description
Překročili jste svůj limit rychlosti.
Name
500 - Internal Server Error
Description
Samotnou kontrolu duševního vlastnictví se nepodařilo dokončit (Unable to perform intellectual property check, please try again). Enterprise účty s povolenou filtrací duševního vlastnictví při této kontrole selžou uzavřeně; nic není účtováno — požadavek zopakujte.
Request
POST
/openapi/creative-lab/fidget-pixel/v1/prototype
# Stage 1: pixelize the source photocurlhttps://api.meshy.ai/openapi/creative-lab/fidget-pixel/v1/prototype \-XPOST \-H"Authorization: Bearer ${YOUR_API_KEY}" \-H'Content-Type: application/json' \-d'{ "image_url": "<your publicly accessible image url or base64-encoded data URI>", "type": "person" }'
Vygeneruje 3D tisknutelné díly z úspěšně dokončené prototypové úlohy. Sestavení
namapuje pixel-artový obrázek prototypu na požadovanou mřížku,
kvantizuje jej na nejvýše color_count barev a vygeneruje jeden
zapadající díl pro každou buňku mřížky. Výstupem je jediný soubor 3MF, ve
kterém je každý díl samostatným objektem označeným svou barvou, připraveným pro
slicer s podporou více filamentů. Podobu odpovědi naleznete v části
Objekt úlohy sestavení Fidget Pixel.
Parametry
Name
input_task_id
Type
string
Povinné
Description
ID úlohy prototypové úlohy vytvořené prostřednictvím téhož koncového bodu OpenAPI. Prototyp musel být vytvořen stejným účtem Meshy a musel dosáhnout stavu SUCCEEDED.
Prototypové úlohy vytvořené přes webovou aplikaci nejsou přijímány — koncový bod pro sestavení přijímá pouze prototypové úlohy vytvořené pomocí POST /openapi/creative-lab/fidget-pixel/v1/prototype a jakýkoli jiný zdroj odmítne s chybou 404.
Name
name
Type
string
Description
Volitelný název úlohy pro zobrazovací účely. Maximálně 100 znaků.
options
Volitelná geometrie dílu. Každé pole má výchozí hodnotu — pošlete pouze ta, která chcete přepsat. Jde o stejné ovládací prvky, jaké nabízí webová aplikace Creative Lab; výška čepu, měřítko víčka a další výrobní přednastavení jsou odvozeny z shape a piece_size_mm a nejsou vystaveny.
Name
shape
Type
string
výchozí square
Description
Půdorys každého dílu. Dostupné hodnoty:
square (výchozí) — čtvercové díly na čtvercové mřížce.
hex — šestiúhelníkové díly na šestiúhelníkové mřížce. Šestiúhelníkové díly jsou dostupné pouze v provedení 6 a 8 mm.
Name
grid_size
Type
integer
výchozí 32
Description
Počet dílů podél každé strany desky. Dostupné hodnoty: 16 nebo 32. Mřížka 32 zachovává více detailů; mřížka 16 znamená méně, ale větší díly pro stejný motiv.
Name
piece_size_mm
Type
integer
výchozí 8
Description
Délka hrany každého dílu v milimetrech. Dostupné hodnoty: 6, 8 nebo 10. Společně s grid_size toto určuje velikost vytištěné desky — například 32 × 8 mm ≈ 26 cm na stranu. Hodnota 10 není dostupná pro shape: "hex" (šikmá plocha šestiúhelníku přesahuje na většině spotřebitelských tiskáren FDM).
Name
color_count
Type
integer
výchozí 8
Description
Maximální počet barev v paletě, na kterou je obrázek kvantizován. Rozsah: [1, 8]. Každá barva se stane jedním filamentem ve vašem sliceru.
Name
piece_height_mm
Type
integer
výchozí 15
Description
Výška každého dílu v milimetrech. Rozsah: [10, 80].
output
Volitelný výběr přenosového formátu. Výchozí hodnota je 3mf, což je aktuálně jediná podporovaná hodnota.
Name
format
Type
string
výchozí 3mf
Description
Artefakt vrácený sestavením. Dostupné hodnoty:
3mf (výchozí) — vrátí jediný soubor model.3mf v poli model_urls.3mf, s jedním objektem na díl a barvou dílu přiřazenou ke každému objektu.
Návratové hodnoty
Vlastnost result v odpovědi obsahuje id úlohy nově vytvořené úlohy sestavení Fidget Pixel. Dotazujte se na koncový bod Získání úlohy nebo se přihlaste k odběru proudu, dokud úloha nedosáhne stavu SUCCEEDED, poté stáhněte artefakt z model_urls.3mf.
Režimy selhání
Name
400 - Bad Request
Description
Požadavek byl nepřijatelný. Běžné příčiny:
Chybějící parametr: input_task_id je povinný.
Neplatné UUID: input_task_id není platné UUID.
Nadřazená úloha nedokončena úspěšně: Odkazovaná prototypová úloha ještě nedosáhla stavu SUCCEEDED.
Žádný kandidát: Prototypová úloha byla úspěšná, ale nevytvořila žádný pixel-artový obrázek; vytvořte nový prototyp.
Volby mimo rozsah: Jedno z polí options je mimo povolenou množinu nebo rozsah — například options.grid_size must be 16 or 32, nebo options.piece_size_mm=10 is not supported for shape=hex; hex pieces are available in 6 and 8 mm.
Nepodporovaný formát: output.format musí být 3mf.
Name
401 - Unauthorized
Description
Autentizace selhala. Zkontrolujte prosím svůj API klíč.
Name
402 - Payment Required
Description
Nedostatek kreditů pro provedení této úlohy, nebo API klíč patří k účtu s bezplatným plánem.
Name
403 - Forbidden
Description
Obrázek odkazovaného prototypu byl označen moderací duševního vlastnictví. Blokovány jsou pouze podnikové (Enterprise) účty s povolenou filtrací duševního vlastnictví; nic se přitom neúčtuje.
Name
404 - Not Found
Description
Odkazovaná prototypová úloha neexistuje, patří jinému uživateli, nebo byla vytvořena přes webovou aplikaci (do sestavení lze zřetězit pouze prototypové úlohy vytvořené v režimu API).
Name
429 - Too Many Requests
Description
Překročili jste svůj limit rychlosti.
Name
500 - Internal Server Error
Description
Verdikt ohledně duševního vlastnictví odkazovaného prototypu se nepodařilo stanovit (Unable to perform intellectual property check, please try again). Podnikové (Enterprise) účty s povolenou filtrací duševního vlastnictví u této kontroly selžou uzavřeně (fail closed); nic se přitom neúčtuje — zopakujte požadavek.
Načte úlohu prototypu nebo sestavení na základě platného id úlohy. Cesta URL
musí odpovídat fázi úlohy — pokud je úloha sestavení načtena přes
/prototype/:id, vrátí se 404, a naopak.
Jedinečný identifikátor úlohy fidget pixel, kterou chcete načíst.
Návratová hodnota
Odpověď obsahuje objekt úlohy fidget pixel. Podoba závisí na tom,
která fáze byla požadována.
Způsoby selhání
Name
400 - Bad Request
Description
id není platné UUID (Invalid ID).
Name
403 - Forbidden
Description
Obrázek úlohy byl označen moderací duševního vlastnictví. Blokovány jsou pouze podnikové účty (Enterprise) s povoleným filtrováním duševního vlastnictví.
Name
404 - Not Found
Description
Úloha neexistuje, patří jinému uživateli, nebo její fáze neodpovídá cestě URL.
Name
500 - Internal Server Error
Description
Kontrolu duševního vlastnictví se nepodařilo dokončit (Unable to perform intellectual property check, please try again); podnikové účty (Enterprise) s povoleným filtrováním duševního vlastnictví v tomto případě selžou uzavřeně (fail closed). Zopakujte požadavek.
Zruší úlohu fidget pixel. Pokud je úloha stále ve stavu PENDING, kredity
spotřebované při vytvoření jsou vráceny. Úlohy, které jsou již ve stavu
IN_PROGRESS, jsou zrušeny bez vrácení kreditů (worker může již spotřebovávat
zdroje). Úlohy, které již dosáhly konečného stavu
(SUCCEEDED, FAILED, CANCELED), nelze zrušit.
Cesta URL musí odpovídat fázi úlohy — DELETE na
/prototype/:buildId vrací 404.
Path Parameters
Name
id
Type
path
Description
Jedinečný identifikátor úlohy fidget pixel, kterou chcete zrušit.
Returns
Při úspěchu vrací 204 No Content s prázdným tělem.
Failure Modes
Name
400 - Bad Request
Description
Požadavek byl nepřijatelný. Časté příčiny:
Neplatné ID: id není platné UUID.
Konečný stav: Úloha je již ve stavu SUCCEEDED, FAILED nebo CANCELED a nelze ji zrušit.
Name
404 - Not Found
Description
Úloha neexistuje, patří jinému uživateli, nebo její fáze neodpovídá cestě URL.
Streamuje aktualizace úlohy fidget pixel v reálném čase prostřednictvím Server-Sent Events (SSE).
Cesta URL musí odpovídat fázi úlohy — otevření streamu na
/prototype/:buildId/stream vyvolá jediný payload event: error se
status_code: 404 a stream se uzavře; chybně formátované id způsobí totéž se
status_code: 400 (Invalid ID).
Parametry
Name
id
Type
path
Description
Jedinečný identifikátor úlohy fidget pixel, kterou chcete streamovat.
Návratová hodnota
Vrací stream objektů úlohy Fidget Pixel Prototype
nebo Fidget Pixel Build ve formě
Server-Sent Events. Každý snímek obsahuje celý objekt úlohy pro danou fázi — stejnou strukturu, jakou vrací
koncový bod Get — takže dokud je úloha PENDING nebo IN_PROGRESS, výstupní
pole jednoduše ještě nejsou naplněna (null, [] nebo {}) a
finished_at je null.
Načte stránkovaný seznam vašich úloh Fidget Pixel pro jednu fázi.
Cesta URL určuje fázi — /prototype vrací úlohy prototypu;
/build vrací úlohy sestavení. Úlohy z druhé fáze nejsou zahrnuty
v žádné z odpovědí.
Parametry cesty
Name
stage
Type
path
Povinné
Description
Buď prototype, nebo build. Kolekce vrací pouze úlohy,
jejichž fáze odpovídá adrese URL — načtení /prototype nikdy nevrátí
úlohy sestavení a naopak.
Parametry dotazu
Name
page_num
Type
integer
výchozí 1
Description
Číslo stránky pro stránkování.
Name
page_size
Type
integer
výchozí 10
Description
Limit velikosti stránky. Maximální povolená hodnota je 100 položek.
Name
sort_by
Type
string
výchozí -created_at
Description
Pole, podle kterého se má řadit. Dostupné hodnoty:
+created_at: Řazení podle času vytvoření vzestupně.
-created_at: Řazení podle času vytvoření sestupně.
Objekt Fidget Pixel Prototype Task je pracovní jednotka, kterou Meshy sleduje
za účelem pixelizace zdrojové fotografie do obrázku v pixel-art stylu. Výstup této
fáze je řetězen do fáze buildu
prostřednictvím input_task_id.
Vlastnosti
Name
id
Type
string
Description
Jedinečný identifikátor úlohy. Ačkoli jako implementační detail používáme pro id úloh k-sortable UUID, neměli byste dělat žádné předpoklady o formátu id.
Name
type
Type
string
Description
Typ úlohy. Hodnota je creative-lab-fidget-pixel-prototype.
Name
name
Type
string
Description
Název úlohy zadaný při jejím vytvoření. Prázdný řetězec, pokud nebyl název zadán.
Name
status
Type
string
Description
Stav úlohy. Možné hodnoty jsou jedna z PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Progress úlohy. Pokud úloha ještě nebyla zahájena, tato vlastnost bude 0. Jakmile úloha uspěje, hodnota se změní na 100.
Name
created_at
Type
timestamp
Description
Časové razítko okamžiku vytvoření úlohy, v milisekundách.
Časové razítko představuje počet milisekund, které uplynuly od 1. ledna 1970 UTC, podle
standardu RFC 3339.
Například pátek 1. září 2023 12:00:00 PM GMT je reprezentován jako 1693569600000. To platí
pro všechna časová razítka v Meshy API.
Name
started_at
Type
timestamp
Description
Časové razítko okamžiku zahájení úlohy, v milisekundách. Pokud úloha ještě nebyla zahájena, tato vlastnost bude null.
Name
finished_at
Type
timestamp
Description
Časové razítko okamžiku dokončení úlohy, v milisekundách. Pokud úloha ještě nebyla dokončena, tato vlastnost bude null.
Name
expires_at
Type
timestamp
Description
Časové razítko okamžiku, kdy vyprší platnost výsledku úlohy, v milisekundách — 3 dny po dokončení úlohy. Enterprise účty uchovávají výsledky API bez omezení (viz Uchování assetů); pro ně je toto časové razítko nastaveno přibližně 100 let dopředu.
Name
preceding_tasks
Type
integer
Description
Počet předcházejících úloh.
Hodnota tohoto pole má smysl pouze v případě, že stav úlohy je PENDING.
Name
task_error
Type
object
Description
Podrobnosti o chybě pro neúspěšné úlohy. Kompletní referenci objektu task_error naleznete v části Chyby.
Name
consumed_credits
Type
integer
Description
Počet kreditů spotřebovaných touto úlohou. Úloze, která dosáhne stavu SUCCEEDED, je účtována plná částka za danou fázi. Úloha, která nikdy nebyla vytvořena (4xx v době požadavku, včetně zamítnutí moderation), se neúčtuje vůbec. Úloha, která dosáhne stavu FAILED, vrací 0 — poplatek je vrácen. Zrušení pomocí DELETE vrátí poplatek pouze v případě, že úloha je stále ve stavu PENDING; úloha, která je již IN_PROGRESS, zůstává zpoplatněna, protože práce již byla vynaložena.
Name
image_urls
Type
array of strings
Description
URL adresy ke stažení obrázku v pixel-art stylu vygenerovaného touto prototypovou úlohou. V současnosti API vždy vrací přesně jeden obrázek; pole je typu array, aby budoucí revize mohly nabídnout více kandidátů bez rušivé změny. Prázdné, dokud úloha nedosáhne stavu SUCCEEDED.
Jedná se o podepsané URL adresy: načítejte je bez hlavičky Authorization. Zůstávají platné až do expires_at, což je 3 dny po finished_at, a opětovné načtení úlohy v tomto časovém okně vrátí identickou URL adresu namísto nově podepsané. Soubory si stáhněte a uložte sami ještě před vypršením platnosti — neexistuje způsob, jak obnovit platnost vypršeného odkazu.
Objekt Fidget Pixel Build Task je pracovní jednotka, kterou Meshy sleduje za
účelem vygenerování tisknutelných dílů z úspěšně dokončeného prototypového
úkolu (task). Build namapuje pixel-art obrázek prototypu na požadovanou mřížku
a publikuje jeden 3MF soubor s barevným označením.
Vlastnosti
Name
id
Type
string
Description
Jedinečný identifikátor úkolu.
Name
type
Type
string
Description
Typ úkolu. Hodnota je creative-lab-fidget-pixel-build.
Name
name
Type
string
Description
Název úkolu zadaný při jeho vytvoření. Prázdný řetězec, pokud nebyl zadán žádný název.
Name
status
Type
string
Description
Stav úkolu. Možné hodnoty jsou PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Postup (progress) úkolu. Pokud úkol ještě nebyl zahájen, tato vlastnost bude 0. Jakmile úkol uspěje, hodnota se změní na 100.
Name
created_at
Type
timestamp
Description
Časové razítko vytvoření úkolu, v milisekundách.
Name
started_at
Type
timestamp
Description
Časové razítko zahájení úkolu, v milisekundách. null, dokud úkol nezačne.
Name
finished_at
Type
timestamp
Description
Časové razítko dokončení úkolu, v milisekundách. null, dokud úkol neskončí.
Name
expires_at
Type
timestamp
Description
Časové razítko vypršení platnosti výsledku úkolu, v milisekundách — 3 dny po dokončení úkolu. Firemní (Enterprise) účty uchovávají výsledky API po neomezenou dobu (viz Uchování assetů); pro ně je toto časové razítko nastaveno přibližně o 100 let dopředu.
Name
preceding_tasks
Type
integer
Description
Počet předcházejících úkolů. Má smysl pouze v případě, že stav je PENDING.
Name
task_error
Type
object
Description
Podrobnosti o chybě u neúspěšných úkolů. Úplný popis objektu task_error naleznete v části Chyby.
Name
consumed_credits
Type
integer
Description
Počet kreditů spotřebovaných tímto úkolem. Úkolu, který dosáhne stavu SUCCEEDED, je účtována plná částka za jeho fázi. Úkol, který nikdy nebyl vytvořen (chyba 4xx v okamžiku požadavku, včetně zamítnutí moderation), není účtován vůbec. Úkol, který skončí ve stavu FAILED, vrací 0 — poplatek je vrácen. Zrušení pomocí DELETE vrátí poplatek pouze tehdy, pokud je úkol stále ve stavu PENDING; úkol, který je již IN_PROGRESS, zůstává zpoplatněn, protože práce již byla vynaložena.
Name
model_urls
Type
object
Description
Stažitelné URL adresy pro vygenerovaný výstup, klíčované podle formátu. Obsahuje přesně jednu položku — formát požadovaný pomocí output.format v požadavku na build. Prázdné, dokud úkol nedosáhne stavu SUCCEEDED.
Jedná se o podepsané URL adresy: načítejte je bez hlavičky Authorization. Zůstávají platné až do expires_at, což je 3 dny po finished_at, a opakované načtení úkolu v tomto časovém okně vrátí identickou URL adresu namísto nově podepsané. Soubory si stáhněte a uložte sami před vypršením platnosti — vypršenou adresu není možné obnovit.
Name
3mf
Type
string
Description
Stažitelná URL adresa souboru 3MF. Jeden objekt na díl, každý označený svou barvou z palety, takže multi-filamentový slicer přiřadí filamenty podle barvy. Přítomno, pokud output.format bylo 3mf (výchozí hodnota).
Kompletní postup: vytvořte prototyp z fotografie, sledujte ho, dokud nedosáhne stavu
SUCCEEDED, vytvořte z něj sestavu (build), sledujte sestavu, dokud nedosáhne stavu
SUCCEEDED, a poté stáhněte 3MF z model_urls.
Vytvoření prototypu obvykle trvá několik minut; sestava se
obvykle dokončí za výrazně méně než minutu. Ve skutečné integraci byste
koncovému uživateli zobrazili položku image_urls prototypu a nechali ho
potvrdit (nebo znovu spustit prototyp) předtím, než utratíte kredity za sestavu.
Complete flow
POST
/openapi/creative-lab/fidget-pixel/v1
#!/usr/bin/env bashset-euopipefail# Requires curl and jq. Point IMAGE_PATH at a local photo, or IMAGE_URL at a public one:# export MESHY_API_KEY=msy_...# export IMAGE_PATH=./portrait.jpg # or: export IMAGE_URL=https://...# export PIXEL_TYPE=person # or: other:"${MESHY_API_KEY:?export MESHY_API_KEY first}"if [[ -z"${IMAGE_PATH:-}"&&-z"${IMAGE_URL:-}" ]]; thenecho"export IMAGE_PATH (local file) or IMAGE_URL (public url) first">&2exit1fiPIXEL_TYPE=${PIXEL_TYPE:-person}BASE="https://api.meshy.ai/openapi/creative-lab/fidget-pixel/v1"AUTH="Authorization: Bearer $MESHY_API_KEY"# api METHOD URL [curl args...] -> prints the response body, non-zero on failure.# Note we do not use -f/--fail: it discards the body, and the body is the only# place the reason appears.api() {local method=$1 url=$2 out http_code bodyshift2 out=$(curl--silent--show-error--max-time60--write-out$'\n%{http_code}' \-X"$method""$url"-H"$AUTH""$@") ||return1 http_code=${out##*$'\n'} body=${out%$'\n'*}if ((http_code >=400)); thenecho"HTTP $http_code for $url: $body">&2return1fiprintf'%s'"$body"}# Each task gets its own 40-minute budget.poll() {local kind=$1 id=$2 delay=5 task_status deadline deadline=$(($(date+%s) + 2400))while:; doif (($(date +%s) >= deadline)); thenecho"gave up waiting for $kind $id">&2return1fi task_status=$(apiGET"$BASE/$kind/$id"|jq-r'.status')echo"$kind: $task_status"case"$task_status"inSUCCEEDED)return0 ;;FAILED|CANCELED)return1 ;;esacsleep"$delay" delay=$((delay*2>30?30:delay*2))done}# Build the request body in a file. A base64 data URI must never go on the# command line or into an exported variable - a photo of any real size will# exceed the OS argument limit.BODY=$(mktemp)trap'rm -f "$BODY"'EXITif [[ -n"${IMAGE_PATH:-}" ]]; then# Declare the real type: the API accepts JPEG, PNG and WebP.case"$(printf '%s' "${IMAGE_PATH##*.}" |tr 'A-Z' 'a-z')"inpng) MIME=image/png ;;webp) MIME=image/webp ;;*) MIME=image/jpeg ;;esac {printf'{"type":"%s","image_url":"data:%s;base64,'"$PIXEL_TYPE""$MIME"base64<"$IMAGE_PATH"|tr-d'\n'printf'"}' } >"$BODY"elsejq-n--argt"$PIXEL_TYPE"--argu"$IMAGE_URL" \'{type: $t, image_url: $u}'>"$BODY"fi# 1. Create the prototype taskPROTO_ID=$(apiPOST"$BASE/prototype" \-H'Content-Type: application/json'--data-binary@"$BODY"|jq-r'.result')# 2. Wait for the pixel-art image (show image_urls[0] to a user in production)pollprototype"$PROTO_ID"# 3. Create the build task (defaults: square pieces, 32x32 grid, 8 mm, 8 colors, 15 mm tall)jq-n--argp"$PROTO_ID" \'{input_task_id: $p, options: {shape: "square", grid_size: 32, piece_size_mm: 8, color_count: 8, piece_height_mm: 15}, output: {format: "3mf"}}'>"$BODY"BUILD_ID=$(apiPOST"$BASE/build" \-H'Content-Type: application/json'--data-binary@"$BODY"|jq-r'.result')# 4. Wait for the piecespollbuild"$BUILD_ID"# 5. Download the 3MF. This is a signed URL: no Authorization header,# and it stays valid for 3 days after the task finishes.TASK=$(apiGET"$BASE/build/$BUILD_ID")curl--silent--show-error--fail--max-time900 \-ofidget-pixel.3mf"$(jq-r '.model_urls["3mf"]' <<<"$TASK")"echo"Done: fidget-pixel.3mf"