Files

8.6 KiB
Raw Permalink Blame History

HartOMat

Ziel

Automatisiertes Render-System für HartOMat-Produktbilder. Kunden (intern) laden Excel-Auftragslisten hoch, das System extrahiert Produktdaten, verknüpft STEP-CAD-Dateien, rendert Thumbnails und Animationen über Blender (Cycles/EEVEE), und liefert fertige PNG/MP4-Ausgaben.

Tech Stack

  • Backend: Python 3.11, FastAPI (async), SQLAlchemy 2 (async), Alembic, Celery, Pydantic v2
  • Frontend: React 18, TypeScript, Vite, Tailwind CSS, lucide-react
  • Datenbank: PostgreSQL 16
  • Queue/Cache: Redis 7 (Celery Broker + Backend)
  • Storage: MinIO (S3-kompatibel)
  • Renderer: Blender 5.0.1 (headless, Cycles GPU)
  • CAD Parsing: OCC (cadquery/OCP) für STEP-Parsing, GMSH 4.15 für Tessellierung
  • USD: usd-core (pxr) für kanonische Szenen-Exporte
  • Deployment: Docker Compose (8 Services)

Services (docker-compose.yml)

Service Port Funktion
postgres 5432 Primärdatenbank
redis 6379 Celery Broker
minio 9000/9001 S3-kompatibler Object Store (MediaAssets)
backend 8888 FastAPI App (uvicorn)
worker Celery Worker, Queue: step_processing, concurrency=8
render-worker Celery Worker, Queue: asset_pipeline, concurrency=1 (Blender)
beat Celery Beat (Scheduler)
frontend 5173 React/Vite Dev Server

Starten / Stoppen

# Alle Services starten
docker compose up -d

# Logs einzelner Services
docker compose logs -f backend
docker compose logs -f worker
docker compose logs -f render-worker

# Neubauen nach Codeänderungen (Backend/Worker)
docker compose up -d --build backend worker render-worker beat

# Frontend-Änderungen: Hot-Reload aktiv, kein Rebuild nötig

Standard-Zugangsdaten (Entwicklung)

Projektstruktur

project-root/
├── backend/
│   ├── app/
│   │   ├── api/routers/          # FastAPI Router (admin, cad, orders, products, ...)
│   │   ├── core/                 # Middleware, pipeline_logger, process_steps, tenant_context
│   │   ├── domains/              # Domain-driven modules (orders, media, pipeline, rendering, tenants, ...)
│   │   │   └── pipeline/tasks/   # Active Celery task implementations
│   │   ├── models/               # SQLAlchemy ORM-Modelle
│   │   ├── services/             # Business-Logik (step_processor, render_blender, material_service, ...)
│   │   ├── tasks/                # Compatibility shim only (step_tasks.py, 23 lines) — do NOT add logic here
│   │   └── utils/                # Auth, Seeding
│   ├── alembic/versions/         # DB-Migrationen (001062+)
│   └── start.sh                  # Entrypoint: migrate → seed → uvicorn
├── render-worker/
│   ├── scripts/                  # Blender/OCC/GMSH subprocess scripts
│   │   ├── blender_render.py     # Entry point (68 lines), delegates to _blender_*.py submodules
│   │   ├── export_step_to_gltf.py  # OCC/GMSH STEP → GLB tessellation
│   │   ├── export_step_to_usd.py   # OCC STEP → USD canonical scene
│   │   ├── import_usd.py         # Blender: USD import + primvar restoration
│   │   ├── still_render.py       # Blender still render
│   │   └── turntable_render.py   # Blender turntable animation
│   └── Dockerfile
├── frontend/src/
│   ├── api/                      # API-Client-Funktionen (axios-basiert)
│   ├── components/               # Wiederverwendbare UI-Komponenten
│   └── pages/                    # Seitenkomponenten
└── docker-compose.yml

Coding-Standards

  • Sprache im Code: Englisch (Variablen, Kommentare, Commits)
  • Commits: Conventional Commits (feat:, fix:, refactor:, docs:)
  • Python: async/await durchgehend im Backend, sync-Wrapper für Celery-Tasks
  • TypeScript: Interfaces für alle API-Responses in frontend/src/api/*.ts
  • Keine Tests: Aktuell kein automatisiertes Test-Suite vorhanden

Datenbank-Migrationen

# Neue Migration erstellen
docker compose exec backend alembic revision --autogenerate -m "beschreibung"

# Migrationen anwenden
docker compose exec backend alembic upgrade head

# Status prüfen
docker compose exec backend alembic current

Celery Task-Queues

Queue Worker Concurrency Tasks
step_processing worker 8 process_step_file, render_order_line_task, dispatch_order_line_render
asset_pipeline render-worker 1 render_step_thumbnail, regenerate_thumbnail, generate_gltf_geometry_task, generate_usd_master_task
ai_validation worker 8 Azure AI Validierung

Wichtig: asset_pipeline läuft mit concurrency=1, weil Blender single-threaded ist. Mehr parallele Tasks führen zu Abstürzen.

Task-Location: Aktive Implementierungen in backend/app/domains/pipeline/tasks/. backend/app/tasks/step_tasks.py ist ein 23-Zeilen Compatibility-Shim — dort keine Logik hinzufügen.

STEP-Processing-Pipeline

  1. Upload: STEP-Datei hochladen → CadFile-Record erstellt → process_step_file Task eingereiht
  2. Metadata (process_step_file auf step_processing):
    • STEP-Objekte extrahieren (OCC/cadquery, ~0.1s)
    • parsed_objects in DB speichern
    • Status: processing → queut render_step_thumbnail
  3. Thumbnail (render_step_thumbnail auf asset_pipeline):
    • OCC/GMSH Tessellierung → GLB
    • Blender Render → Thumbnail PNG
    • Status: completed oder failed
    • Materialien auto-populated
  4. USD Export (generate_usd_master_task auf asset_pipeline):
    • OCC XCAF → USD mit Hierarchie, Materialien, Primvars
    • Blender Cycles Render konsumiert USD direkt
  5. Still/Turntable Render (render_order_line_task auf step_processing → dispatches to asset_pipeline):
    • Konsumiert usd_master MediaAsset (nicht GLB)
    • Blender Cycles GPU → PNG/MP4

Material-Alias-System

  • Materialien werden per STEP-Part-Name auf HartOMat-Bibliotheksmaterialien (HARTOMAT_...) gemappt
  • Lookup-Reihenfolge: Alias-Tabelle zuerst, dann exakter Material.name-Match, dann Pass-through
  • Alias-Seeding: Admin → "Seed Aliases" oder via POST /api/materials/seed-aliases

Rollen

Rolle Berechtigungen
global_admin Vollzugriff, Admin-Panel, alle Einstellungen, plattformweite Operationen
tenant_admin Mandant verwalten, Nutzer im eigenen Mandant
project_manager Aufträge, Analytics, Render-Trigger
client Eigene Aufträge anlegen und einsehen

Auth Guards: require_global_admin (platform-level), require_pm_or_above (admin/PM), get_current_user + manual check.

Wichtige API-Endpoints

  • POST /api/uploads/excel — Excel-Auftragsliste importieren
  • POST /api/orders/{id}/submit — Auftrag einreichen
  • POST /api/orders/{id}/dispatch-renders — Alle Render-Zeilen dispatchen
  • GET /api/cad/{id}/thumbnail — Thumbnail (kein Auth, UUID opaque)
  • POST /api/cad/{id}/generate-gltf-geometry — Geometry GLB Export triggern
  • POST /api/cad/{id}/generate-usd-master — USD Master Export triggern
  • GET /api/cad/{id}/scene-manifest — Part-Keys mit Material-Zuweisungen
  • POST /api/admin/settings/regenerate-thumbnails — Alle Thumbnails neu rendern
  • POST /api/admin/settings/process-unprocessed — Unverarbeitete STEP-Dateien queuen
  • GET /api/worker/activity — Letzte 30 STEP-Verarbeitungen (Status, Timing)

Bekannte Eigenheiten

  • Backend-Port 8888 (nicht 8000 — war belegt)
  • Tailwind CSS-Variablen: bg-surface etc. funktionieren nicht mit / opacity-Syntax wenn CSS-Variable einen Hex-Wert enthält. Stattdessen style={{ backgroundColor: 'var(--color-bg-surface)' }} verwenden.
  • Blender mm→m: STEP-Dateien sind in mm, Blender intern in m. Alle Import-Scripts skalieren mit 0.001.
  • USD Koordinaten: OCC Z-up → USD Y-up Transformation via Matrix auf /Root/Assembly Xform.
  • settings_persistence: Admin-Einstellungen werden via direktem SQL-UPDATE gespeichert (nicht ORM-Mutation), da SQLAlchemy bei key-value-Stores keine Mutation trackt.
  • Prim-Namen: USD Prim-Namen dürfen nicht mit Ziffern beginnen. p_-Prefix wird automatisch für Teile wie 439505389 gesetzt.

Learnings-Pflicht

Nach jedem gelösten Problem oder jeder wichtigen Entscheidung: → Trag das Learning in LEARNINGS.md ein (Format: Datum | Kategorie | Problem → Lösung) → Commitiere LEARNINGS.md zusammen mit dem Fix: docs: learning erfasst - [kurzbeschreibung]