Library-Thumbnails: Auto-Capture + Base64-Preview in der UI
Beim Hinzufuegen oder Importieren eines Library-Items wird automatisch ein PNG-Thumbnail vom Item generiert (Top-View, 128x128) und in library/previews/<id>.png abgelegt. Frontend rendert die Previews als Base64-Data-URIs (sicher gegen WebKit-file://-Restriktionen). library.py: - _previews_dir(): legt previews/-Folder an - _preview_rel_for(asset_rel): predictable PNG-Pfad pro Item - _capture_thumbnail_of_objects(): hided andere Objekte temporaer, switcht auf Top-Parallel, ZoomBoundingBox, CaptureToBitmap → PNG, restored Viewport + Hidden-State - read_preview_data_uri(): liest PNG + encoded als data:image/png;base64 - Hook in convert_to_3dm_via_import (vor Cleanup) + save_selection_to_asset rhinopanel.py: - _enrich_library_items_with_previews(): haengt previewDataUri an jedes Item das ein preview-Feld hat - Initial-Params + _send_library + ElementeBridge._cmd_list_library liefern angereicherte Items - _add_library_file + _save_selection_as_library setzen preview-Pfad im Item wenn Thumbnail-Datei existiert Frontend: - SymbolPicker.ItemPreview: rendert <div backgroundImage> mit Base64-URI wenn vorhanden, sonst Icon-Fallback - ProjectSettingsDialog Symbole-Tab: List-Row + Detail-Identity zeigen Thumbnail (32px in Liste, 56px im Detail), Icon nur als Fallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+38
-8
@@ -147,6 +147,24 @@ def _list_hatch_patterns_full(doc):
|
||||
return out
|
||||
|
||||
|
||||
def _enrich_library_items_with_previews(items):
|
||||
"""Liefert Liste mit zusaetzlichem 'previewDataUri'-Feld pro Item
|
||||
(base64-PNG falls preview-Datei existiert). Items werden NICHT
|
||||
persistiert — nur fuer den Transport ans Frontend angereichert."""
|
||||
import library
|
||||
out = []
|
||||
for it in (items or []):
|
||||
if not isinstance(it, dict):
|
||||
out.append(it); continue
|
||||
enriched = dict(it)
|
||||
prev = it.get("preview")
|
||||
if prev:
|
||||
uri = library.read_preview_data_uri(prev)
|
||||
if uri: enriched["previewDataUri"] = uri
|
||||
out.append(enriched)
|
||||
return out
|
||||
|
||||
|
||||
def _list_linetypes_full(doc):
|
||||
"""Vollstaendiges Linetype-Listing fuer die Verwaltungs-UI.
|
||||
Mac Rhino 8 GetSegment(i) returnt (length: float, isLine: bool):
|
||||
@@ -893,7 +911,8 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
try:
|
||||
import library
|
||||
lib_manifest = library.load_manifest()
|
||||
lib_items = lib_manifest.get("items", [])
|
||||
lib_items = _enrich_library_items_with_previews(
|
||||
lib_manifest.get("items", []))
|
||||
lib_root = library.library_root()
|
||||
except Exception:
|
||||
lib_items = []; lib_root = ""
|
||||
@@ -1183,12 +1202,15 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
# ---- Library-Item CRUD ----
|
||||
def _send_library(self):
|
||||
"""Sendet aktuelle Library-Items ans Frontend
|
||||
(LIBRARY_ITEMS-Message)."""
|
||||
(LIBRARY_ITEMS-Message). Items kommen mit
|
||||
previewDataUri (base64 PNG) wenn Vorschau vorhanden."""
|
||||
try:
|
||||
import library
|
||||
m = library.load_manifest()
|
||||
enriched = _enrich_library_items_with_previews(
|
||||
m.get("items", []))
|
||||
self.send("LIBRARY_ITEMS", {
|
||||
"items": m.get("items", []),
|
||||
"items": enriched,
|
||||
"libraryRoot": library.library_root(),
|
||||
})
|
||||
except Exception as ex:
|
||||
@@ -1247,18 +1269,21 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
self.send("LIBRARY_ERROR", {
|
||||
"msg": "Konnte Datei nicht importieren — siehe Log."})
|
||||
return
|
||||
# Preview-Pfad falls Thumbnail erzeugt wurde
|
||||
preview_rel = library._preview_rel_for(rel)
|
||||
preview_abs = os.path.join(library.library_root(), preview_rel)
|
||||
has_preview = os.path.isfile(preview_abs)
|
||||
if target_id:
|
||||
# Bestehendes Item updaten
|
||||
m = library.load_manifest()
|
||||
for it in m.get("items", []):
|
||||
if it.get("id") == target_id:
|
||||
key = "files" + variant
|
||||
it[key] = [rel]
|
||||
if not it.get("type"): it["type"] = item_type
|
||||
if has_preview: it["preview"] = preview_rel
|
||||
break
|
||||
library.save_manifest(m)
|
||||
else:
|
||||
# Neues Item — stem aus dem Pfad oben bereits berechnet
|
||||
import uuid as _uuid
|
||||
new_id = "obj-" + _uuid.uuid4().hex[:10]
|
||||
item = {
|
||||
@@ -1269,6 +1294,7 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
"tags": [],
|
||||
"files" + variant: [rel],
|
||||
}
|
||||
if has_preview: item["preview"] = preview_rel
|
||||
library.add_item(item)
|
||||
self._send_library()
|
||||
except Exception as ex:
|
||||
@@ -1343,10 +1369,13 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
self.send("LIBRARY_ERROR", {
|
||||
"msg": "Konnte Selection nicht speichern."})
|
||||
return
|
||||
preview_rel = library._preview_rel_for(rel)
|
||||
preview_abs = os.path.join(library.library_root(), preview_rel)
|
||||
has_preview = os.path.isfile(preview_abs)
|
||||
if target_id:
|
||||
library.update_item(target_id, {
|
||||
("files" + variant): [rel],
|
||||
})
|
||||
patch = {("files" + variant): [rel]}
|
||||
if has_preview: patch["preview"] = preview_rel
|
||||
library.update_item(target_id, patch)
|
||||
else:
|
||||
import uuid as _uuid
|
||||
new_id = "obj-" + _uuid.uuid4().hex[:10]
|
||||
@@ -1358,6 +1387,7 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
"tags": [],
|
||||
("files" + variant): [rel],
|
||||
}
|
||||
if has_preview: item["preview"] = preview_rel
|
||||
library.add_item(item)
|
||||
self._send_library()
|
||||
b = _ProjectSettingsBridge()
|
||||
|
||||
Reference in New Issue
Block a user