📝 Nočna Session Setup - Asset Generation Infrastructure
- Created overnight generation system
- Added master character references (Gronk, Kai)
- Implemented auto-commit for all generated assets
- Created comprehensive documentation and changelogs
- Setup FULL generator (850+ assets without NPCs)
- Added progress tracking and status check scripts
Ready for overnight mass generation 🌙
This commit is contained in:
145
CHANGELOG_29_12_2025.md
Normal file
145
CHANGELOG_29_12_2025.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# 📝 Changelog - 29.12.2025
|
||||
|
||||
## 🌙 Nočna Session (03:00 - 09:00)
|
||||
|
||||
### **Glavna Aktivnost:**
|
||||
Avtomatska generacija FULL asset set-a za DolinaSmrti
|
||||
|
||||
---
|
||||
|
||||
## ✅ Opravljeno:
|
||||
|
||||
### **1. Character Reference System**
|
||||
- ✅ Upload master reference slik (Gronk, Kai)
|
||||
- ✅ Kreiran `reference_images/` directory
|
||||
- ✅ Dokumentacija v `CHARACTER_REFERENCES.md`
|
||||
- ✅ NPCs izključeni iz avtomatske generacije
|
||||
|
||||
### **2. Test Generacije**
|
||||
- ✅ Regeneriran Gronk walking frame (z master ref)
|
||||
- ✅ Regeneriran Kai walking frame (z master ref)
|
||||
- ✅ Test samples iz vsake kategorije
|
||||
- ✅ Kvalitetni check - APPROVED
|
||||
|
||||
### **3. Generator Setup**
|
||||
- ✅ Posodobljen `generate_local_final.py` z auto-commit
|
||||
- ✅ Kreiran `test_category_samples.py`
|
||||
- ✅ Kreiran `regenerate_with_master_ref.py`
|
||||
- ✅ Kreiran `generate_full_auto.py` za FULL set
|
||||
|
||||
### **4. Automation Scripts**
|
||||
- ✅ `run_auto_generation.sh` - background runner
|
||||
- ✅ `check_generation_status.sh` - napredek checker
|
||||
- ✅ Auto-commit functionality (Git)
|
||||
- ✅ Auto-open images za review
|
||||
|
||||
### **5. Dokumentacija**
|
||||
- ✅ `AUTO_GENERATION_README.md`
|
||||
- ✅ `CHARACTER_REFERENCES.md`
|
||||
- ✅ `NOCNA_GENERACIJA_LOG.md` (ta datoteka)
|
||||
- ✅ Session changelog
|
||||
|
||||
---
|
||||
|
||||
## 🎯 V Teku:
|
||||
|
||||
### **FULL Asset Generation**
|
||||
- **Start:** ~03:45
|
||||
- **Target:** ~850 slik
|
||||
- **Categories:** Buildings, Workstations, Items, Animals, Environment, Mutants, Bosses, UI
|
||||
- **Excluded:** NPCs, Main Characters
|
||||
- **ETA:** ~09:00 (5-6 ur)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistika:
|
||||
|
||||
### **Pred Generacijo:**
|
||||
- PNG slik: 150
|
||||
- Git commits: ~50
|
||||
|
||||
### **Po Generaciji (target):**
|
||||
- PNG slik: ~1,000
|
||||
- Git commits: ~900
|
||||
- Kategorij: 8
|
||||
- Total MB: ~150-300 MB
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Tehnični Detajli:
|
||||
|
||||
### **ComfyUI Setup:**
|
||||
- Lokalni server: `127.0.0.1:8000`
|
||||
- Model: Dreamshaper 8
|
||||
- Version: 0.6.0
|
||||
- Status: Running ✅
|
||||
|
||||
### **Processing:**
|
||||
- Generation: ComfyUI workflow
|
||||
- Background removal: rembg (u2net model)
|
||||
- Format: PNG (transparent)
|
||||
- Size: 512x512 (bosses 768x768)
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Issues Fixed:
|
||||
|
||||
1. ✅ NPCs excluded iz automation (user request)
|
||||
2. ✅ Master reference integration
|
||||
3. ✅ Git auto-commit dodano
|
||||
4. ✅ Progress tracking izboljšano
|
||||
|
||||
---
|
||||
|
||||
## 📅 Naslednji Koraki (Za Jutri):
|
||||
|
||||
### **Prioriteta 1: Review**
|
||||
- [ ] Pregled vseh generiranih slik
|
||||
- [ ] Kvalitetni check po kategorijah
|
||||
- [ ] Identifikacija slab generiranih
|
||||
|
||||
### **Prioriteta 2: NPCs (Manual)**
|
||||
- [ ] Pregled NPC lista
|
||||
- [ ] Generacija z master reference style
|
||||
- [ ] Review vsake slike posebej
|
||||
|
||||
### **Prioriteta 3: Assets Integration**
|
||||
- [ ] Import v game
|
||||
- [ ] Test v Tiled
|
||||
- [ ] Animation sequences
|
||||
|
||||
---
|
||||
|
||||
## 💾 Backup Info:
|
||||
|
||||
**Git Status:**
|
||||
- Branch: master
|
||||
- Auto-commits: Enabled
|
||||
- Remote: Ready for push
|
||||
|
||||
**Files Modified:**
|
||||
- `scripts/generate_*.py` (multiple)
|
||||
- `reference_images/*`
|
||||
- `assets/images/*` (mass update)
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Asset Breakdown:
|
||||
|
||||
| Category | Target | Status |
|
||||
|:---|---:|:---|
|
||||
| Buildings | 57 | Generira se |
|
||||
| Workstations | 25 | Generira se |
|
||||
| Items | 505 | Generira se |
|
||||
| Animals | 147 | Generira se |
|
||||
| Environment | 103 | Generira se |
|
||||
| Mutants | 98 | Generira se |
|
||||
| Bosses | 25 | Generira se |
|
||||
| UI | 41 | Generira se |
|
||||
| **TOTAL** | **1,001** | **V teku** |
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 29.12.2025 03:43
|
||||
**Next Review:** 29.12.2025 09:00 (zjutraj)
|
||||
**Status:** 🟢 RUNNING
|
||||
154
NOCNA_GENERACIJA_LOG.md
Normal file
154
NOCNA_GENERACIJA_LOG.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# 🌙 NOČNA GENERACIJA - Session Log
|
||||
**Datum:** 29. December 2025, 03:42
|
||||
**Status:** AVTOMATSKA GENERACIJA V TEKU
|
||||
|
||||
---
|
||||
|
||||
## 📋 ČE BERETE TO ZJUTRAJ:
|
||||
|
||||
Pozdravljen! Tukaj je kratek pregled kaj je bilo narejeno med spanjem.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 CILJ NOČNE GENERACIJE:
|
||||
|
||||
**FULL Asset Set** - ~850 slik (BREZ NPCs in glavnih karakterjev)
|
||||
|
||||
### **Vključeno:**
|
||||
- ✅ **Buildings** (57) - Farm, Production, Town buildings
|
||||
- ✅ **Workstations** (25) - Crafting stations
|
||||
- ✅ **Items** (505) - Tools, weapons, potions, food
|
||||
- ✅ **Animals** (147) - Farm, wildlife, legendary
|
||||
- ✅ **Environment** (103) - Trees, objects, terrain
|
||||
- ✅ **Mutanti** (98) - Zombies, slimes
|
||||
- ✅ **Bosses** (25) - Epic encounters
|
||||
- ✅ **UI** (41) - Interface elements
|
||||
|
||||
### **IZKLJUČENO:**
|
||||
- ❌ NPCs (~85)
|
||||
- ❌ Main Characters (Gronk, Kai, Ana)
|
||||
|
||||
---
|
||||
|
||||
## 📊 PRED GENERACIJO:
|
||||
|
||||
**Že generirano:** 150 PNG slik
|
||||
**Cilj:** ~1,000 PNG slik (FULL set brez NPCs)
|
||||
**Manjka:** ~850 slik
|
||||
|
||||
---
|
||||
|
||||
## ⏱️ ČASOVNI OKVIR:
|
||||
|
||||
**Ocena:** 5-6 ur
|
||||
**Start:** 29.12.2025 ~03:45
|
||||
**Predviden konec:** 29.12.2025 ~09:00
|
||||
|
||||
---
|
||||
|
||||
## 🔧 TEHNIČNI DETAJLI:
|
||||
|
||||
### **Generator:**
|
||||
- Script: `generate_full_auto.py`
|
||||
- ComfyUI: Local port 8000
|
||||
- Model: Dreamshaper 8
|
||||
- Background removal: rembg (u2net)
|
||||
- Auto-commit: DA (vsaka slika)
|
||||
|
||||
### **Konfiguratcija:**
|
||||
- Size: 512x512 (bosses 768x768)
|
||||
- Steps: 30
|
||||
- CFG: 7.5
|
||||
- Sampler: euler_ancestral
|
||||
- Scheduler: karras
|
||||
|
||||
---
|
||||
|
||||
## 📁 OUTPUT:
|
||||
|
||||
Vse slike v:
|
||||
```
|
||||
/Users/davidkotnik/repos/novafarma/assets/images/
|
||||
├── items/
|
||||
├── buildings/
|
||||
├── workstations/
|
||||
├── environment/
|
||||
├── zivali/
|
||||
├── mutanti/
|
||||
├── bosses/
|
||||
└── ui/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 GIT COMMITS:
|
||||
|
||||
Vsaka slika se avtomatsko committa:
|
||||
```
|
||||
🎨 Auto-generated: [category]/[filename]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 KAKO PREVERITI NAPREDEK:
|
||||
|
||||
### **1. Pregled logov:**
|
||||
```bash
|
||||
cat /Users/davidkotnik/repos/novafarma/generation_progress.log
|
||||
```
|
||||
|
||||
### **2. Status check:**
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma/scripts
|
||||
./check_generation_status.sh
|
||||
```
|
||||
|
||||
### **3. Štetje slik:**
|
||||
```bash
|
||||
find /Users/davidkotnik/repos/novafarma/assets/images -name "*.png" | wc -l
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ ČE JE VSE OK:
|
||||
|
||||
Pričakujete:
|
||||
- **~1,000 PNG slik** v `/assets/images/`
|
||||
- **~850 Git commits**
|
||||
- **Vse transparentne** (rembg processed)
|
||||
- **Organizirano po kategorijah**
|
||||
|
||||
---
|
||||
|
||||
## ❌ ČE NEKAJ NI V REDU:
|
||||
|
||||
Preverite:
|
||||
1. `generation_progress.log` - za errore
|
||||
2. ComfyUI je še vedno running
|
||||
3. Disk space (vsaka slika ~100-300 KB)
|
||||
|
||||
---
|
||||
|
||||
## 🎨 MASTER REFERENCES:
|
||||
|
||||
**Važno:** NPCs ostanejo ročno, ker uporabljamo master reference:
|
||||
- `reference_images/MASTER_GRONK.png`
|
||||
- `reference_images/MASTER_KAI.png`
|
||||
|
||||
---
|
||||
|
||||
## 📈 NASLEDNJI KORAKI (za zjutraj):
|
||||
|
||||
1. ✅ Pregled kvalitete slik
|
||||
2. ✅ Če je OK → lahko začnemo z NPCs (ročno)
|
||||
3. ✅ Če ni OK → debug in ponovna generacija
|
||||
|
||||
---
|
||||
|
||||
**Generated:** 29.12.2025 03:42
|
||||
**By:** Antigravity AI Assistant
|
||||
**Purpose:** Overnight mass asset generation for DolinaSmrti game
|
||||
|
||||
---
|
||||
|
||||
**Lep počitek in pohvale za jutro!** 🌟
|
||||
80
reference_images/CHARACTER_REFERENCES.md
Normal file
80
reference_images/CHARACTER_REFERENCES.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# 🎨 MASTER CHARACTER REFERENCES
|
||||
|
||||
These are the **DEFINITIVE** character designs. ALL generated assets MUST match these exact styles.
|
||||
|
||||
## 🧌 GRONK - Master Reference
|
||||

|
||||
|
||||
**Key Features:**
|
||||
- **Skin**: Green-grey, visible belly
|
||||
- **Hair**: BRIGHT PINK dreadlocks with ear gauges
|
||||
- **Face**: Piercings (nose ring, ear piercings), peaceful zen expression
|
||||
- **Clothing**:
|
||||
- Black t-shirt with "TROLL SABBATH" purple text
|
||||
- Black baggy pants (loose fit)
|
||||
- PINK sneakers (bright magenta)
|
||||
- **Props**: Colorful vape device with pink/purple smoke
|
||||
- **Body**: Large, overweight, relaxed posture
|
||||
|
||||
**Exact Prompt Template:**
|
||||
```
|
||||
Gronk the troll character, green-grey skin with visible round belly,
|
||||
BRIGHT PINK dreadlocks, large ear gauges, nose ring and facial piercings,
|
||||
wearing black baggy t-shirt with purple "TROLL SABBATH" text,
|
||||
black loose baggy pants, bright pink sneakers,
|
||||
holding colorful rainbow vape device with pink smoke,
|
||||
peaceful relaxed expression, full body
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 👤 KAI - Master Reference
|
||||

|
||||
|
||||
**Key Features:**
|
||||
- **Skin**: Medium tone, clean
|
||||
- **Hair**: DARK GREEN thick dreadlocks (forest green, not lime)
|
||||
- **Face**: Ear gauges (stretched lobes), nose piercing, lip piercing, serious expression
|
||||
- **Clothing**:
|
||||
- Blue-grey weathered denim jacket (dirt stains, wear marks)
|
||||
- Beige/tan undershirt
|
||||
- Ripped blue jeans (torn at knees)
|
||||
- Brown leather combat boots (laced up)
|
||||
- Brown survival backpack with pockets and straps
|
||||
- **Build**: Teenage, athletic, lean
|
||||
- **Posture**: Determined, survivor stance
|
||||
|
||||
**Exact Prompt Template:**
|
||||
```
|
||||
Kai teenage survivor character, dark forest green thick dreadlocks,
|
||||
medium skin tone, large ear gauges, nose piercing and lip piercing,
|
||||
serious determined expression,
|
||||
wearing weathered blue-grey denim jacket with dirt stains,
|
||||
beige t-shirt underneath,
|
||||
torn blue jeans ripped at knees,
|
||||
brown leather combat boots,
|
||||
brown survival backpack with straps and pockets,
|
||||
athletic lean build, full body
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 USAGE INSTRUCTIONS
|
||||
|
||||
1. **All Gronk animations** must use the Gronk template
|
||||
2. **All Kai animations** must use the Kai template
|
||||
3. **Color accuracy is critical**:
|
||||
- Gronk's pink = `#FF1493` (bright magenta)
|
||||
- Kai's green = `#2D5016` (dark forest green)
|
||||
4. **Include ALL details** - piercings, clothing text, wear/dirt
|
||||
5. **Match proportions** - Gronk is wide/heavy, Kai is lean/athletic
|
||||
|
||||
---
|
||||
|
||||
## 📝 REGENERATION NEEDED
|
||||
|
||||
The following files were generated BEFORE these references and need regeneration:
|
||||
- `npcs/gronk_front_walk1.png` ❌
|
||||
- `npcs/kai_front_walk1.png` ❌
|
||||
|
||||
Delete and regenerate with correct prompts.
|
||||
BIN
reference_images/MASTER_GRONK.png
Normal file
BIN
reference_images/MASTER_GRONK.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
BIN
reference_images/MASTER_KAI.png
Normal file
BIN
reference_images/MASTER_KAI.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 554 KiB |
124
scripts/AUTO_GENERATION_README.md
Normal file
124
scripts/AUTO_GENERATION_README.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# 🎮 DOLINA SMRTI - Avtomatska Generacija Assetsov
|
||||
|
||||
## 🚀 NAČIN 1: Popolnoma Avtomatsko (PRIPOROČENO)
|
||||
|
||||
### Zagon:
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma/scripts
|
||||
./run_auto_generation.sh
|
||||
```
|
||||
|
||||
**To bo:**
|
||||
- ✅ Zagnalo generacijo v ozadju
|
||||
- ✅ Kreiral log datoteko z timestampom
|
||||
- ✅ Omogočil da zaprete terminal ALI greste spat
|
||||
- ✅ ComfyUI že teče, zato bo začel takoj
|
||||
|
||||
**Po zagonu lahko:**
|
||||
- Zaprete terminal - proces bo tekel naprej
|
||||
- Ugasnete zaslon - proces bo tekel naprej
|
||||
- Greste spat - proces bo tekel naprej
|
||||
|
||||
---
|
||||
|
||||
## 📊 Spremljanje Napredka
|
||||
|
||||
### Preveri status:
|
||||
```bash
|
||||
./check_generation_status.sh
|
||||
```
|
||||
|
||||
### Live spremljanje (real-time):
|
||||
```bash
|
||||
tail -f /Users/davidkotnik/repos/novafarma/generation_*.log
|
||||
```
|
||||
|
||||
Za izhod iz live pogleda: **Ctrl+C**
|
||||
|
||||
---
|
||||
|
||||
## ⏹️ Ustavitev Generacije
|
||||
|
||||
Če želite ustaviti:
|
||||
```bash
|
||||
kill $(cat /tmp/dolina_generation.pid)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 NAČIN 2: Terminal Session (za debugging)
|
||||
|
||||
Če želite videti output v realnem času:
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma/scripts
|
||||
python3 generate_local_final.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⏱️ Časovni Okvir
|
||||
|
||||
**Na podlagi testov:**
|
||||
- ⏱️ ~15-30 sekund na asset
|
||||
- 📊 **110 remaining assets** = ~45-90 minut
|
||||
- 📊 **422 total V7 assets** = ~3-5 ur
|
||||
- 📊 **1,418 full assets** = ~10-18 ur
|
||||
|
||||
**Ker ComfyUI teče lokalno:**
|
||||
- ❌ BREZ API rate limitov
|
||||
- ❌ BREZ pavz
|
||||
- ❌ BREZ potrebe po vaši prisotnosti
|
||||
- ✅ Lahko teče ČEZNOJI
|
||||
|
||||
---
|
||||
|
||||
## 📁 Rezultati
|
||||
|
||||
Vsi generirani PNG-ji so avtomatsko:
|
||||
- ✅ Odstranjeno ozadje (transparentni)
|
||||
- ✅ Shranjeni v `/Users/davidkotnik/repos/novafarma/assets/images/`
|
||||
- ✅ Razvrščeni po kategorijah
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Možne Težave
|
||||
|
||||
### ComfyUI se ne odziva:
|
||||
1. Odprite ComfyUI app
|
||||
2. Počakajte da se zažene (zeleni indikator)
|
||||
3. Poskusite znova
|
||||
|
||||
### Generacija se ne začne:
|
||||
```bash
|
||||
# Preverite error log:
|
||||
cat /Users/davidkotnik/repos/novafarma/generation_*.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Nasveti
|
||||
|
||||
**ZA ČEZ NOČ:**
|
||||
1. Zaženite: `./run_auto_generation.sh`
|
||||
2. Greste spat 😴
|
||||
3. Zjutraj: `./check_generation_status.sh`
|
||||
4. Profit! 🎉
|
||||
|
||||
**ZA PREMIUM REZULTATE:**
|
||||
- ComfyUI uporablja **Dreamshaper 8** model
|
||||
- Vsaka slika je **512x512** (bosses 768x768)
|
||||
- Background removal z **rembg (u2net model)**
|
||||
- **30 generation steps** za kakovost
|
||||
|
||||
---
|
||||
|
||||
## 📈 Trenutni Status
|
||||
|
||||
Po zadnjem preverjanju:
|
||||
- ✅ ComfyUI: **v teku** (port 8000)
|
||||
- 📊 Generirano: **148/422** (V7) ali **148/1,418** (FULL)
|
||||
- ⏳ Manjka: **~274 slik** za V7 set
|
||||
|
||||
---
|
||||
|
||||
**🎯 Glavna Prednost: Lahko vse teče AVTOMATSKO čez noč!** 🌙
|
||||
49
scripts/check_generation_status.sh
Executable file
49
scripts/check_generation_status.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# 🔍 Preveri status generacije
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🎮 DOLINA SMRTI - Asset Generation Status"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# Preveri če proces teče
|
||||
if [ -f /tmp/dolina_generation.pid ]; then
|
||||
PID=$(cat /tmp/dolina_generation.pid)
|
||||
if ps -p $PID > /dev/null 2>&1; then
|
||||
echo "✅ Generacija TEČE (PID: $PID)"
|
||||
|
||||
# Pokaži zadnje loge
|
||||
LATEST_LOG=$(ls -t /Users/davidkotnik/repos/novafarma/generation_*.log 2>/dev/null | head -1)
|
||||
if [ -n "$LATEST_LOG" ]; then
|
||||
echo "📂 Log file: $LATEST_LOG"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📊 Zadnjih 15 vrstic:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
tail -15 "$LATEST_LOG"
|
||||
fi
|
||||
else
|
||||
echo "❌ Proces NE teče več (PID $PID ni aktiven)"
|
||||
rm /tmp/dolina_generation.pid
|
||||
fi
|
||||
else
|
||||
echo "⭕ Generacija NI zagnana"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📁 Trenutno generirane slike:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
cd /Users/davidkotnik/repos/novafarma/assets/images
|
||||
for dir in */; do
|
||||
count=$(find "$dir" -name "*.png" 2>/dev/null | wc -l)
|
||||
printf " %-20s: %3d slik\n" "${dir%/}" "$count"
|
||||
done
|
||||
|
||||
total=$(find . -name "*.png" 2>/dev/null | wc -l)
|
||||
echo " ────────────────────────────────"
|
||||
printf " %-20s: %3d slik\n" "SKUPAJ" "$total"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
161
scripts/fresh_test.py
Normal file
161
scripts/fresh_test.py
Normal file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🚀 FRESH TEST - Generira 3 nove slike ki jih še ni
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
print("📦 Installing rembg...")
|
||||
os.system("pip3 install --user rembg pillow onnxruntime")
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
# Configuration
|
||||
COMFYUI_URL = "http://127.0.0.1:8000"
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
|
||||
|
||||
STYLE = "2D indie game sprite, cartoon vector style, clean smooth lines, full body visible, isolated on pure white background"
|
||||
NEGATIVE = "pixel art, pixelated, 3d, realistic, photo, blurry, watermark, text, green background"
|
||||
|
||||
# 🆕 NOVE SLIKE - Še ne generirane
|
||||
NEW_ASSETS = [
|
||||
("npcs", "gronk_front_walk1", "Gronk massive troll, PINK dreadlocks, black baggy t-shirt and pants, pink sneakers, holding vape, front view walking left leg forward"),
|
||||
("npcs", "kai_front_walk1", "Kai teenage survivor, GREEN dreadlocks, blue jacket, torn jeans, boots, front view walking left leg forward"),
|
||||
("zivali", "fox_red", "red fox wildlife animal, bushy tail, clever expression, side view"),
|
||||
]
|
||||
|
||||
|
||||
def log(msg):
|
||||
ts = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{ts}] {msg}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def git_commit(file_path, category, name):
|
||||
"""Auto-commit generated asset"""
|
||||
try:
|
||||
rel_path = file_path.relative_to(REPO_DIR)
|
||||
subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True)
|
||||
subprocess.run(["git", "commit", "-m", f"🎨 Generated: {category}/{name}"], cwd=REPO_DIR, check=True, capture_output=True)
|
||||
log(f" 📝 Git committed: {rel_path}")
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def create_workflow(prompt_text, output_name, size=512):
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
full_prompt = f"{STYLE}, {prompt_text}"
|
||||
|
||||
return {
|
||||
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
|
||||
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
|
||||
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
|
||||
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "clip": ["1", 1]}},
|
||||
"5": {
|
||||
"class_type": "KSampler",
|
||||
"inputs": {
|
||||
"seed": seed, "steps": 30, "cfg": 7.5,
|
||||
"sampler_name": "euler_ancestral", "scheduler": "karras",
|
||||
"denoise": 1.0, "model": ["1", 0],
|
||||
"positive": ["3", 0], "negative": ["4", 0], "latent_image": ["2", 0]
|
||||
}
|
||||
},
|
||||
"6": {"class_type": "VAEDecode", "inputs": {"samples": ["5", 0], "vae": ["1", 2]}},
|
||||
"7": {"class_type": "SaveImage", "inputs": {"filename_prefix": output_name, "images": ["6", 0]}}
|
||||
}
|
||||
|
||||
|
||||
def queue_prompt(workflow):
|
||||
try:
|
||||
r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"}, timeout=10)
|
||||
return r.json().get("prompt_id")
|
||||
except Exception as e:
|
||||
log(f"❌ Queue error: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def wait_completion(prompt_id, timeout=120):
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
|
||||
if prompt_id in r.json() and r.json()[prompt_id].get("outputs"):
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
return False
|
||||
|
||||
|
||||
def download_and_process(prompt_id, output_path):
|
||||
try:
|
||||
h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json()
|
||||
for out in h.get(prompt_id, {}).get("outputs", {}).values():
|
||||
for img in out.get("images", []):
|
||||
r = requests.get(f"{COMFYUI_URL}/view", params={"filename": img["filename"], "subfolder": img.get("subfolder", ""), "type": "output"})
|
||||
if r.status_code == 200:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
from io import BytesIO
|
||||
transparent_img = remove(Image.open(BytesIO(r.content)))
|
||||
transparent_img.save(str(output_path), "PNG")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
log(f"❌ Download error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
log("="*60)
|
||||
log("🚀 FRESH TEST - Generiranje Novih Slik")
|
||||
log(" Z avtomatskim Git commitom")
|
||||
log("="*60)
|
||||
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
|
||||
log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']} running")
|
||||
except:
|
||||
log("❌ ComfyUI not running!")
|
||||
return
|
||||
|
||||
log(f"\n🎯 Generating {len(NEW_ASSETS)} new assets...\n")
|
||||
|
||||
for i, (cat, name, prompt) in enumerate(NEW_ASSETS, 1):
|
||||
path = OUTPUT_DIR / cat / f"{name}.png"
|
||||
|
||||
if path.exists():
|
||||
log(f"[{i}/{len(NEW_ASSETS)}] ⏭️ {name} - skipping (exists)")
|
||||
continue
|
||||
|
||||
log(f"[{i}/{len(NEW_ASSETS)}] 🎨 {name}...")
|
||||
|
||||
wf = create_workflow(prompt, name, 512)
|
||||
pid = queue_prompt(wf)
|
||||
|
||||
if pid and wait_completion(pid) and download_and_process(pid, path):
|
||||
log(f" ✅ Generated & transparent!")
|
||||
git_commit(path, cat, name)
|
||||
else:
|
||||
log(f" ❌ FAILED")
|
||||
|
||||
log("\n" + "="*60)
|
||||
log("🚀 FRESH TEST COMPLETE!")
|
||||
log("="*60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -11,6 +11,7 @@ import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
@@ -116,6 +117,40 @@ def log(msg):
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def git_commit(file_path, category, name):
|
||||
"""Auto-commit generated asset to Git"""
|
||||
try:
|
||||
repo_dir = Path("/Users/davidkotnik/repos/novafarma")
|
||||
rel_path = file_path.relative_to(repo_dir)
|
||||
|
||||
# Git add
|
||||
subprocess.run(
|
||||
["git", "add", str(rel_path)],
|
||||
cwd=repo_dir,
|
||||
check=True,
|
||||
capture_output=True
|
||||
)
|
||||
|
||||
# Git commit
|
||||
commit_msg = f"🎨 Auto-generated asset: {category}/{name}"
|
||||
result = subprocess.run(
|
||||
["git", "commit", "-m", commit_msg],
|
||||
cwd=repo_dir,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
log(f" 📝 Git committed")
|
||||
return True
|
||||
else:
|
||||
# Možno da je že committed ali ni sprememb
|
||||
return False
|
||||
except Exception as e:
|
||||
log(f" ⚠️ Git: {str(e)[:50]}")
|
||||
return False
|
||||
|
||||
|
||||
def create_workflow(prompt_text, output_name, size=512):
|
||||
"""Create ComfyUI workflow"""
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
@@ -271,6 +306,8 @@ def main():
|
||||
|
||||
if pid and wait_completion(pid) and download_and_process(pid, path):
|
||||
log(f" ✅ DONE (transparent)")
|
||||
# Auto-commit to Git
|
||||
git_commit(path, cat, name)
|
||||
success += 1
|
||||
else:
|
||||
log(f" ❌ FAILED")
|
||||
|
||||
175
scripts/regenerate_with_master_ref.py
Normal file
175
scripts/regenerate_with_master_ref.py
Normal file
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎨 REGENERATE - Z Master Reference
|
||||
Uporablja točne specifikacije iz MASTER_GRONK.png in MASTER_KAI.png
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
os.system("pip3 install --user rembg pillow onnxruntime")
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
COMFYUI_URL = "http://127.0.0.1:8000"
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
|
||||
|
||||
STYLE = "2D indie game cartoon character sprite, clean vector style, smooth bold outlines, full body visible head to feet, isolated on pure white background"
|
||||
NEGATIVE = "pixel art, pixelated, 3d render, realistic photo, anime, manga, blurry, watermark, text, green background, cut off"
|
||||
|
||||
# 🎯 CORRECT PROMPTS based on MASTER references
|
||||
CORRECT_ASSETS = [
|
||||
("npcs", "gronk_front_walk1",
|
||||
"Gronk the troll character, green-grey skin with visible round belly, "
|
||||
"BRIGHT PINK dreadlocks, large ear gauges, nose ring and facial piercings, "
|
||||
"wearing black baggy t-shirt with purple TROLL SABBATH text, "
|
||||
"black loose baggy pants, bright pink sneakers, "
|
||||
"holding colorful rainbow vape device with pink smoke, "
|
||||
"peaceful relaxed expression, full body, front view, walking pose left leg forward"),
|
||||
|
||||
("npcs", "kai_front_walk1",
|
||||
"Kai teenage survivor character, dark forest green thick dreadlocks, "
|
||||
"medium skin tone, large ear gauges, nose piercing and lip piercing, "
|
||||
"serious determined expression, "
|
||||
"wearing weathered blue-grey denim jacket with dirt stains, "
|
||||
"beige t-shirt underneath, "
|
||||
"torn blue jeans ripped at knees, "
|
||||
"brown leather combat boots, "
|
||||
"brown survival backpack with straps and pockets, "
|
||||
"athletic lean build, full body, front view, walking pose left leg forward"),
|
||||
]
|
||||
|
||||
|
||||
def log(msg):
|
||||
ts = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{ts}] {msg}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def git_commit(file_path, category, name):
|
||||
try:
|
||||
rel_path = file_path.relative_to(REPO_DIR)
|
||||
subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True)
|
||||
subprocess.run(["git", "commit", "-m", f"🎨 CORRECT: {category}/{name} (master ref)"], cwd=REPO_DIR, check=True, capture_output=True)
|
||||
log(f" 📝 Git committed with master ref tag")
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def create_workflow(prompt_text, output_name, size=512):
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
full_prompt = f"{STYLE}, {prompt_text}"
|
||||
|
||||
return {
|
||||
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
|
||||
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
|
||||
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
|
||||
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "clip": ["1", 1]}},
|
||||
"5": {
|
||||
"class_type": "KSampler",
|
||||
"inputs": {
|
||||
"seed": seed, "steps": 35, "cfg": 8.0,
|
||||
"sampler_name": "euler_ancestral", "scheduler": "karras",
|
||||
"denoise": 1.0, "model": ["1", 0],
|
||||
"positive": ["3", 0], "negative": ["4", 0], "latent_image": ["2", 0]
|
||||
}
|
||||
},
|
||||
"6": {"class_type": "VAEDecode", "inputs": {"samples": ["5", 0], "vae": ["1", 2]}},
|
||||
"7": {"class_type": "SaveImage", "inputs": {"filename_prefix": output_name, "images": ["6", 0]}}
|
||||
}
|
||||
|
||||
|
||||
def queue_prompt(workflow):
|
||||
try:
|
||||
r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"regen_{uuid.uuid4().hex[:8]}"}, timeout=10)
|
||||
return r.json().get("prompt_id")
|
||||
except Exception as e:
|
||||
log(f"❌ Queue error: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def wait_completion(prompt_id, timeout=120):
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
|
||||
if prompt_id in r.json() and r.json()[prompt_id].get("outputs"):
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
return False
|
||||
|
||||
|
||||
def download_and_process(prompt_id, output_path):
|
||||
try:
|
||||
h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json()
|
||||
for out in h.get(prompt_id, {}).get("outputs", {}).values():
|
||||
for img in out.get("images", []):
|
||||
r = requests.get(f"{COMFYUI_URL}/view", params={"filename": img["filename"], "subfolder": img.get("subfolder", ""), "type": "output"})
|
||||
if r.status_code == 200:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
from io import BytesIO
|
||||
transparent_img = remove(Image.open(BytesIO(r.content)))
|
||||
transparent_img.save(str(output_path), "PNG")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
log(f"❌ Download error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
log("="*70)
|
||||
log("🎨 REGENERATE - Z Master Reference Slikami")
|
||||
log(" Točne specifikacije iz MASTER_GRONK.png & MASTER_KAI.png")
|
||||
log("="*70)
|
||||
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
|
||||
log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']} running")
|
||||
except:
|
||||
log("❌ ComfyUI not running!")
|
||||
return
|
||||
|
||||
log(f"\n🎯 Regenerating {len(CORRECT_ASSETS)} characters with CORRECT style...\n")
|
||||
|
||||
for i, (cat, name, prompt) in enumerate(CORRECT_ASSETS, 1):
|
||||
path = OUTPUT_DIR / cat / f"{name}.png"
|
||||
|
||||
log(f"[{i}/{len(CORRECT_ASSETS)}] 🎨 {name}...")
|
||||
log(f" 📋 Using master reference prompt")
|
||||
|
||||
wf = create_workflow(prompt, name, 512)
|
||||
pid = queue_prompt(wf)
|
||||
|
||||
if pid and wait_completion(pid) and download_and_process(pid, path):
|
||||
log(f" ✅ Generated with CORRECT style!")
|
||||
git_commit(path, cat, name)
|
||||
|
||||
# Auto-open to verify
|
||||
os.system(f"open {path}")
|
||||
else:
|
||||
log(f" ❌ FAILED")
|
||||
|
||||
log("\n" + "="*70)
|
||||
log("🎨 REGENERATION COMPLETE!")
|
||||
log(" Slike so odprte - preverite ali sedaj ustrezajo!")
|
||||
log("="*70)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
37
scripts/run_auto_generation.sh
Executable file
37
scripts/run_auto_generation.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
# 🎮 DOLINA SMRTI - Avtomatski generator
|
||||
# Teče v ozadju, logs v datoteko
|
||||
|
||||
cd /Users/davidkotnik/repos/novafarma/scripts
|
||||
|
||||
# Kreiraj log file z timestampom
|
||||
LOG_FILE="/Users/davidkotnik/repos/novafarma/generation_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
echo "🎮 Starting DOLINA SMRTI Asset Generation..."
|
||||
echo "📂 Logs: $LOG_FILE"
|
||||
echo "⏱️ Start time: $(date)"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "🔥 Generation je v teku... lahko zaprete terminal ali pustite račun vklopljen."
|
||||
echo " Za preverjanje statusa: tail -f $LOG_FILE"
|
||||
echo ""
|
||||
|
||||
# Zaženi generacijo v ozadju z logs
|
||||
nohup python3 generate_local_final.py > "$LOG_FILE" 2>&1 &
|
||||
|
||||
# Shrani PID
|
||||
PID=$!
|
||||
echo "✅ Process ID: $PID"
|
||||
echo "$PID" > /tmp/dolina_generation.pid
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📊 Za spremljanje napredka (live):"
|
||||
echo " tail -f $LOG_FILE"
|
||||
echo ""
|
||||
echo "⏹️ Za ustavitev generacije:"
|
||||
echo " kill $PID"
|
||||
echo ""
|
||||
echo "🎯 Ko je končano, rezultat bo v:"
|
||||
echo " /Users/davidkotnik/repos/novafarma/assets/images/"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
201
scripts/test_category_samples.py
Normal file
201
scripts/test_category_samples.py
Normal file
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🧪 CATEGORY TEST SAMPLES
|
||||
Po 1 stvar iz vsake kategorije - kvalitetni check pred množično generacijo
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
os.system("pip3 install --user rembg pillow onnxruntime")
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
COMFYUI_URL = "http://127.0.0.1:8000"
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
|
||||
|
||||
STYLE = "2D indie game sprite, cartoon vector style, clean smooth outlines, full body visible, isolated on pure white background"
|
||||
NEGATIVE = "pixel art, pixelated, 3d render, realistic photo, anime, blurry, watermark, text, green background"
|
||||
|
||||
# 🧪 TEST SAMPLES - Po 1 iz vsake kategorije (BREZ NPCs!)
|
||||
TEST_SAMPLES = [
|
||||
# Živali
|
||||
("zivali", "rabbit_white", "white rabbit animal, long ears, fluffy tail, cute, side view"),
|
||||
|
||||
# Bosses
|
||||
("bosses", "boss_dragon_ice", "Ice Dragon boss, massive blue dragon, frost breath, ice scales, menacing, full body"),
|
||||
|
||||
# Items - Tool
|
||||
("items", "tool_pickaxe_iron", "iron pickaxe tool, metal head, wooden handle, mining equipment"),
|
||||
|
||||
# Items - Weapon
|
||||
("items", "weapon_bow_wood", "wooden bow with arrow, hunting weapon, medieval style"),
|
||||
|
||||
# Items - Magic
|
||||
("items", "wand_lightning", "lightning magic wand, yellow crystal tip, electric sparks, glowing"),
|
||||
|
||||
# Items - Potion
|
||||
("items", "potion_mana", "mana potion, blue liquid in glass bottle, magical glow"),
|
||||
|
||||
# Items - Food
|
||||
("items", "food_bread", "bread loaf, fresh baked, brown crust, artisan style"),
|
||||
|
||||
# Environment - Tree
|
||||
("environment", "tree_pine", "pine tree, evergreen, cone shaped, forest tree, full tree"),
|
||||
|
||||
# Environment - Object
|
||||
("environment", "barrel_wood", "wooden storage barrel, medieval style, brown wood"),
|
||||
|
||||
# Mutanti
|
||||
("mutanti", "slime_purple", "purple poison slime monster, bouncing blob, toxic bubbles"),
|
||||
]
|
||||
|
||||
|
||||
def log(msg):
|
||||
ts = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{ts}] {msg}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def git_commit(file_path, category, name):
|
||||
try:
|
||||
rel_path = file_path.relative_to(REPO_DIR)
|
||||
subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True)
|
||||
subprocess.run(["git", "commit", "-m", f"🧪 Test sample: {category}/{name}"], cwd=REPO_DIR, check=True, capture_output=True)
|
||||
log(f" 📝 Committed")
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def create_workflow(prompt_text, output_name, size=512):
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
full_prompt = f"{STYLE}, {prompt_text}"
|
||||
|
||||
return {
|
||||
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
|
||||
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
|
||||
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
|
||||
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "clip": ["1", 1]}},
|
||||
"5": {
|
||||
"class_type": "KSampler",
|
||||
"inputs": {
|
||||
"seed": seed, "steps": 30, "cfg": 7.5,
|
||||
"sampler_name": "euler_ancestral", "scheduler": "karras",
|
||||
"denoise": 1.0, "model": ["1", 0],
|
||||
"positive": ["3", 0], "negative": ["4", 0], "latent_image": ["2", 0]
|
||||
}
|
||||
},
|
||||
"6": {"class_type": "VAEDecode", "inputs": {"samples": ["5", 0], "vae": ["1", 2]}},
|
||||
"7": {"class_type": "SaveImage", "inputs": {"filename_prefix": output_name, "images": ["6", 0]}}
|
||||
}
|
||||
|
||||
|
||||
def queue_prompt(workflow):
|
||||
try:
|
||||
r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"}, timeout=10)
|
||||
return r.json().get("prompt_id")
|
||||
except Exception as e:
|
||||
log(f"❌ {e}")
|
||||
return None
|
||||
|
||||
|
||||
def wait_completion(prompt_id, timeout=120):
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
|
||||
if prompt_id in r.json() and r.json()[prompt_id].get("outputs"):
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
return False
|
||||
|
||||
|
||||
def download_and_process(prompt_id, output_path):
|
||||
try:
|
||||
h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json()
|
||||
for out in h.get(prompt_id, {}).get("outputs", {}).values():
|
||||
for img in out.get("images", []):
|
||||
r = requests.get(f"{COMFYUI_URL}/view", params={"filename": img["filename"], "subfolder": img.get("subfolder", ""), "type": "output"})
|
||||
if r.status_code == 200:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
from io import BytesIO
|
||||
transparent_img = remove(Image.open(BytesIO(r.content)))
|
||||
transparent_img.save(str(output_path), "PNG")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
log(f"❌ {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
log("="*70)
|
||||
log("🧪 CATEGORY TEST SAMPLES")
|
||||
log(" Po 1 iz vsake kategorije - kvalitetni check")
|
||||
log(" NPCs IZKLJUČENI iz avtomatike!")
|
||||
log("="*70)
|
||||
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
|
||||
log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']}")
|
||||
except:
|
||||
log("❌ ComfyUI not running!")
|
||||
return
|
||||
|
||||
log(f"\n🎯 Generating {len(TEST_SAMPLES)} test samples...\n")
|
||||
|
||||
success = 0
|
||||
|
||||
for i, (cat, name, prompt) in enumerate(TEST_SAMPLES, 1):
|
||||
path = OUTPUT_DIR / cat / f"{name}.png"
|
||||
|
||||
if path.exists():
|
||||
log(f"[{i}/{len(TEST_SAMPLES)}] ⏭️ {name} - exists")
|
||||
continue
|
||||
|
||||
log(f"[{i}/{len(TEST_SAMPLES)}] 🎨 {cat}/{name}")
|
||||
|
||||
size = 768 if cat == "bosses" else 512
|
||||
wf = create_workflow(prompt, name, size)
|
||||
pid = queue_prompt(wf)
|
||||
|
||||
if pid and wait_completion(pid) and download_and_process(pid, path):
|
||||
log(f" ✅ Done!")
|
||||
git_commit(path, cat, name)
|
||||
success += 1
|
||||
|
||||
# Open image immediately for review
|
||||
os.system(f"open {path}")
|
||||
else:
|
||||
log(f" ❌ Failed")
|
||||
|
||||
# Brief pause between generations
|
||||
if i < len(TEST_SAMPLES):
|
||||
time.sleep(2)
|
||||
|
||||
log("\n" + "="*70)
|
||||
log(f"🧪 TEST SAMPLES COMPLETE! ({success}/{len(TEST_SAMPLES)})")
|
||||
log(" Slike so odprte - preverite kakovost!")
|
||||
log("="*70)
|
||||
log("\n💡 Če je kakovost OK → lahko zaženem VSE ostale")
|
||||
log(" (items, environment, animals, bosses, mutants)")
|
||||
log(" NPCs ostanejo ROČNO!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
209
scripts/test_generation.py
Executable file
209
scripts/test_generation.py
Executable file
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🧪 TEST GENERATION - Generira 5 testnih slik
|
||||
Z avtomatskim Git commitom
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
print("📦 Installing rembg...")
|
||||
os.system("pip3 install --user rembg pillow onnxruntime")
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
# Configuration
|
||||
COMFYUI_URL = "http://127.0.0.1:8000"
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
REPO_DIR = Path("/Users/davidkotnik/repos/novafarma")
|
||||
|
||||
STYLE = "2D indie game sprite, cartoon vector style, clean smooth lines, full body visible, isolated on pure white background #FFFFFF"
|
||||
NEGATIVE = "pixel art, pixelated, 3d, realistic, photo, blurry, watermark, text, green background"
|
||||
|
||||
# 🧪 TEST ASSETS - Par hitrih testnih slik
|
||||
TEST_ASSETS = [
|
||||
("npcs", "npc_elder", "wise tribal elder NPC, walking stick, long white beard, robes"),
|
||||
("npcs", "npc_child", "survivor orphan child NPC, oversized clothes, teddy bear"),
|
||||
("zivali", "goat_brown", "brown goat farm animal, small horns, playful"),
|
||||
("items", "tool_hammer", "hammer building tool, wooden handle"),
|
||||
("environment", "flower_red", "red flowers patch, blooming"),
|
||||
]
|
||||
|
||||
|
||||
def log(msg):
|
||||
ts = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{ts}] {msg}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def git_commit(file_path, category, name):
|
||||
"""Auto-commit generated asset"""
|
||||
try:
|
||||
rel_path = file_path.relative_to(REPO_DIR)
|
||||
|
||||
# Git add
|
||||
subprocess.run(
|
||||
["git", "add", str(rel_path)],
|
||||
cwd=REPO_DIR,
|
||||
check=True,
|
||||
capture_output=True
|
||||
)
|
||||
|
||||
# Git commit
|
||||
commit_msg = f"🎨 Generated asset: {category}/{name}"
|
||||
subprocess.run(
|
||||
["git", "commit", "-m", commit_msg],
|
||||
cwd=REPO_DIR,
|
||||
check=True,
|
||||
capture_output=True
|
||||
)
|
||||
|
||||
log(f" ✅ Git committed: {rel_path}")
|
||||
return True
|
||||
except subprocess.CalledProcessError as e:
|
||||
log(f" ⚠️ Git commit failed (možno že committed): {e}")
|
||||
return False
|
||||
|
||||
|
||||
def create_workflow(prompt_text, output_name, size=512):
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
full_prompt = f"{STYLE}, {prompt_text}"
|
||||
|
||||
return {
|
||||
"1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}},
|
||||
"2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}},
|
||||
"3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}},
|
||||
"4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "clip": ["1", 1]}},
|
||||
"5": {
|
||||
"class_type": "KSampler",
|
||||
"inputs": {
|
||||
"seed": seed, "steps": 30, "cfg": 7.5,
|
||||
"sampler_name": "euler_ancestral", "scheduler": "karras",
|
||||
"denoise": 1.0, "model": ["1", 0],
|
||||
"positive": ["3", 0], "negative": ["4", 0], "latent_image": ["2", 0]
|
||||
}
|
||||
},
|
||||
"6": {"class_type": "VAEDecode", "inputs": {"samples": ["5", 0], "vae": ["1", 2]}},
|
||||
"7": {"class_type": "SaveImage", "inputs": {"filename_prefix": output_name, "images": ["6", 0]}}
|
||||
}
|
||||
|
||||
|
||||
def queue_prompt(workflow):
|
||||
try:
|
||||
r = requests.post(
|
||||
f"{COMFYUI_URL}/prompt",
|
||||
json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"},
|
||||
timeout=10
|
||||
)
|
||||
return r.json().get("prompt_id")
|
||||
except Exception as e:
|
||||
log(f"❌ Queue error: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def wait_completion(prompt_id, timeout=120):
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
|
||||
data = r.json()
|
||||
if prompt_id in data and data[prompt_id].get("outputs"):
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
return False
|
||||
|
||||
|
||||
def download_and_process(prompt_id, output_path):
|
||||
try:
|
||||
h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json()
|
||||
for out in h.get(prompt_id, {}).get("outputs", {}).values():
|
||||
for img in out.get("images", []):
|
||||
r = requests.get(f"{COMFYUI_URL}/view", params={
|
||||
"filename": img["filename"],
|
||||
"subfolder": img.get("subfolder", ""),
|
||||
"type": "output"
|
||||
})
|
||||
if r.status_code == 200:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Remove background
|
||||
from io import BytesIO
|
||||
src_img = Image.open(BytesIO(r.content))
|
||||
transparent_img = remove(src_img)
|
||||
transparent_img.save(str(output_path), "PNG")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
log(f"❌ Download error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
log("=" * 60)
|
||||
log("🧪 TEST GENERATION - 5 Testnih Slik")
|
||||
log(" Z avtomatskim Git commitom")
|
||||
log("=" * 60)
|
||||
|
||||
# Check ComfyUI
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
|
||||
v = r.json()["system"]["comfyui_version"]
|
||||
log(f"✅ ComfyUI v{v} running")
|
||||
except:
|
||||
log("❌ ComfyUI not running!")
|
||||
return
|
||||
|
||||
log(f"\n🎯 Generating {len(TEST_ASSETS)} test assets...\n")
|
||||
|
||||
success, fail = 0, 0
|
||||
start_time = time.time()
|
||||
|
||||
for i, (cat, name, prompt) in enumerate(TEST_ASSETS, 1):
|
||||
path = OUTPUT_DIR / cat / f"{name}.png"
|
||||
|
||||
# Skip if exists
|
||||
if path.exists():
|
||||
log(f"[{i}/{len(TEST_ASSETS)}] ⏭️ {name} - already exists")
|
||||
continue
|
||||
|
||||
log(f"[{i}/{len(TEST_ASSETS)}] 🎨 Generating {name}...")
|
||||
|
||||
wf = create_workflow(prompt, name, 512)
|
||||
pid = queue_prompt(wf)
|
||||
|
||||
if pid and wait_completion(pid) and download_and_process(pid, path):
|
||||
log(f" ✅ Image saved (transparent)")
|
||||
|
||||
# Auto-commit
|
||||
git_commit(path, cat, name)
|
||||
|
||||
success += 1
|
||||
else:
|
||||
log(f" ❌ FAILED")
|
||||
fail += 1
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
log("\n" + "=" * 60)
|
||||
log("🧪 TEST COMPLETE!")
|
||||
log(f" ✅ Success: {success}")
|
||||
log(f" ❌ Failed: {fail}")
|
||||
log(f" ⏱️ Time: {elapsed:.1f}s ({elapsed/60:.1f} min)")
|
||||
log(f" 📁 Output: {OUTPUT_DIR}")
|
||||
log("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user