Auswahl als Library-Item speichern (Step 3)
User selektiert in Rhino → klickt im Symbole-Tab 'Aus Auswahl' → Selection wird in eine .3dm-Datei verpackt + Library-Item entsteht (oder bestehendes wird aktualisiert). Backend (library.py): - save_selection_to_asset(doc, target_name): erstellt File3dm aus der aktuellen Selection, packt Geometry relativ zu BoundingBox.Min (Block- Origin am Ursprung), schreibt nach library/assets/ Backend (ProjectSettingsBridge): - SAVE_SELECTION_AS_LIBRARY-Handler: holt Selection, fragt bei neuen Items via Rhino-GetString nach Name, schreibt .3dm, fuegt Item zum Manifest oder updated bestehendes (variant '2d'/'3d') Frontend (Symbole-Tab): - List-Footer: 'Aus Datei' + 'Aus Auswahl' Pills (neues Item) - Pro 2D/3D-Slot im Detail: 'Datei wählen' + 'Aus Auswahl' Pills (Variante eines bestehenden Items befüllen) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -210,6 +210,91 @@ def add_item(item):
|
||||
return ok, load_manifest()
|
||||
|
||||
|
||||
def save_selection_to_asset(doc, target_name):
|
||||
"""Speichert die aktuelle Selection aus dem Doc als eigene .3dm-Datei
|
||||
in library/assets/<target_name>.3dm. Returns relativer Pfad oder None.
|
||||
Geometry wird relativ zum BoundingBox-Min platziert damit der Block-
|
||||
Origin am Ursprung sitzt — sinnvoll fuer Symbol-Insert."""
|
||||
if doc is None or not target_name: return None
|
||||
try:
|
||||
sel = list(doc.Objects.GetSelectedObjects(False, False))
|
||||
except Exception:
|
||||
sel = []
|
||||
if not sel:
|
||||
print("[LIBRARY] save_selection: keine Auswahl")
|
||||
return None
|
||||
if Rhino is None: return None
|
||||
ensure_library()
|
||||
assets_dir = os.path.join(library_root(), "assets")
|
||||
if not os.path.isdir(assets_dir):
|
||||
try: os.makedirs(assets_dir)
|
||||
except Exception: pass
|
||||
# Safe filename
|
||||
safe = "".join(c if (c.isalnum() or c in "-_") else "_" for c in target_name)
|
||||
if not safe.endswith(".3dm"): safe += ".3dm"
|
||||
target = os.path.join(assets_dir, safe)
|
||||
if os.path.isfile(target):
|
||||
stem, ext = os.path.splitext(safe)
|
||||
n = 2
|
||||
while os.path.isfile(os.path.join(assets_dir, "{}_{}{}".format(stem, n, ext))):
|
||||
n += 1
|
||||
target = os.path.join(assets_dir, "{}_{}{}".format(stem, n, ext))
|
||||
# File3dm aufbauen + Selection rein
|
||||
try:
|
||||
from Rhino.FileIO import File3dm, File3dmWriteOptions
|
||||
import Rhino.Geometry as rg
|
||||
# BoundingBox sammeln um geometrie an Ursprung zu verschieben
|
||||
bbox = rg.BoundingBox.Empty
|
||||
geoms = []
|
||||
for o in sel:
|
||||
g = o.Geometry
|
||||
if g is None: continue
|
||||
try:
|
||||
bb = g.GetBoundingBox(True)
|
||||
if bb.IsValid: bbox.Union(bb)
|
||||
except Exception: pass
|
||||
geoms.append((g, o.Attributes))
|
||||
if not geoms:
|
||||
return None
|
||||
if not bbox.IsValid:
|
||||
origin = rg.Point3d(0, 0, 0)
|
||||
else:
|
||||
origin = bbox.Min
|
||||
offset = rg.Transform.Translation(-origin.X, -origin.Y, -origin.Z)
|
||||
f3 = File3dm()
|
||||
for g, a in geoms:
|
||||
try:
|
||||
g2 = g.Duplicate()
|
||||
try: g2.Transform(offset)
|
||||
except Exception: pass
|
||||
# Generischer Add fuer alle GeometryBase
|
||||
try: f3.Objects.Add(g2, a)
|
||||
except Exception:
|
||||
# Fallback: typ-spezifisch
|
||||
if isinstance(g2, rg.Brep): f3.Objects.AddBrep(g2)
|
||||
elif isinstance(g2, rg.Curve): f3.Objects.AddCurve(g2)
|
||||
elif isinstance(g2, rg.Mesh): f3.Objects.AddMesh(g2)
|
||||
elif isinstance(g2, rg.Point): f3.Objects.AddPoint(g2.Location)
|
||||
except Exception as ex:
|
||||
print("[LIBRARY] save_selection add:", ex)
|
||||
# Write
|
||||
try:
|
||||
opts = File3dmWriteOptions()
|
||||
opts.Version = 8
|
||||
f3.Write(target, opts)
|
||||
except Exception:
|
||||
try: f3.Write(target, 8)
|
||||
except Exception as ex:
|
||||
print("[LIBRARY] save_selection write:", ex)
|
||||
return None
|
||||
rel = os.path.relpath(target, library_root())
|
||||
print("[LIBRARY] save_selection: {} objs → {}".format(len(geoms), rel))
|
||||
return rel
|
||||
except Exception as ex:
|
||||
print("[LIBRARY] save_selection:", ex)
|
||||
return None
|
||||
|
||||
|
||||
def copy_to_assets(src_path, target_name=None):
|
||||
"""Kopiert eine Datei in library/assets/. target_name optional (sonst
|
||||
Original-Name). Returns relativer Pfad ('assets/foo.3dm') oder None."""
|
||||
|
||||
Reference in New Issue
Block a user