Files
DOSSIER/tools/export_icons.py
T
karim 9dc191be4f Initial commit — Dossier Rhino 8 Plugin
OpenStudio-Suite Architektur-Plugin fuer Rhino 8 (Mac):
- Smart-Elemente: Wand, Decke, Dach (Pult/Sattel/Walm/Mansarde),
  Oeffnungen (Fenster/Tueren mit Rahmen + Sims + Glas + Fluegel),
  Treppen (gerade · L · Wendel mit Schrittmass-Validierung)
- Live-Previews mit Step-Lines + Soll-Range-Clamping
- Bidirektionale Selection-Sync zwischen Source-Linie und Volume
- Geschoss-/Ebenen-Verwaltung mit OKFF-Persistenz
- Layouts mit PDF-Export
- Ausschnitte / Massstab / Override-Regeln
- Petrol-Gruen Theme (Rapport-konform)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 04:27:41 +02:00

162 lines
5.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
export_icons.py
Laedt alle Material-Symbols-Outlined Icons herunter die unsere WERKZEUGE-
Sidebar benutzt, und konvertiert sie zu PNG (32x32) fuer Rhino-Toolbars.
Ausgabe-Ordner: ./icons_export/
dossier_icons/
svg/ — Originale SVGs (skalierbar)
png/ — 32x32 PNGs fuer Rhino .rui Buttons
Konvertierung SVG->PNG nutzt 'rsvg-convert' wenn installiert, sonst Mac's
'qlmanage' (immer verfuegbar) als Fallback.
Verwendung:
python3 tools/export_icons.py
"""
import os
import sys
import shutil
import subprocess
from urllib.request import urlopen, Request
# Icons gruppiert wie in WerkzeugeApp.jsx — name : label (label nur fuer Logging)
ICONS = {
# 2D Zeichnen
"horizontal_rule": "Line",
"polyline": "Polyline",
"rectangle": "Rect",
"radio_button_unchecked": "Circle",
"network_intelligence": "Arc",
"gesture": "Curve",
"text_fields": "Text",
"grid_view": "Hatch",
"straighten": "Dim",
# 2D Editieren
"open_with": "Move",
"content_copy": "Copy",
"rotate_right": "Rotate",
"aspect_ratio": "Scale",
"flip": "Mirror",
"padding": "Offset",
"content_cut": "Trim",
"swipe_right_alt": "Extend",
"link": "Join",
"scatter_plot": "Explode",
"rounded_corner": "Fillet",
"apps": "Array",
# 3D Modellieren
"vertical_align_top": "Extrude",
"square": "Box",
"join_inner": "Union",
"remove": "Diff",
"gradient": "Intersect",
"roofing": "Cap",
"cut": "Section",
"unfold_more": "Loft",
# Auswahl
"add_link": "SelChain",
"filter_alt": "SelDup",
"loop": "SelClosed",
"compare_arrows": "Invert",
"select_all": "SelAll",
"deselect": "SelNone",
}
URL_TPL = "https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/{name}/default/24px.svg"
OUT_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "icons_export", "dossier_icons")
OUT_SVG = os.path.join(OUT_ROOT, "svg")
OUT_PNG = os.path.join(OUT_ROOT, "png")
def ensure_dirs():
for d in (OUT_SVG, OUT_PNG):
if not os.path.isdir(d):
os.makedirs(d)
def download_svg(name):
url = URL_TPL.format(name=name)
req = Request(url, headers={"User-Agent": "Mozilla/5.0"})
with urlopen(req, timeout=10) as r:
return r.read()
def have(cmd):
return shutil.which(cmd) is not None
def convert_to_png(svg_path, png_path, size=32):
"""Konvertiert SVG -> PNG. Probiert rsvg-convert, sonst qlmanage (Mac)."""
if have("rsvg-convert"):
try:
subprocess.check_call(
["rsvg-convert", "-w", str(size), "-h", str(size),
svg_path, "-o", png_path],
stderr=subprocess.DEVNULL,
)
return "rsvg-convert"
except subprocess.CalledProcessError:
pass
if have("qlmanage"):
# qlmanage erzeugt {svg_path}.png im out-dir
out_dir = os.path.dirname(png_path)
try:
subprocess.check_call(
["qlmanage", "-t", "-s", str(size), "-o", out_dir, svg_path],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
)
generated = svg_path + ".png"
generated_in_outdir = os.path.join(out_dir, os.path.basename(generated))
if os.path.isfile(generated_in_outdir):
shutil.move(generated_in_outdir, png_path)
return "qlmanage"
except subprocess.CalledProcessError:
pass
return None
def main():
ensure_dirs()
print("[icons] Ziel: " + os.path.abspath(OUT_ROOT))
n_ok = 0
n_png = 0
n_fail = []
converter_used = None
for name, label in sorted(ICONS.items()):
svg_path = os.path.join(OUT_SVG, name + ".svg")
try:
data = download_svg(name)
with open(svg_path, "wb") as f:
f.write(data)
n_ok += 1
# SVG -> PNG
png_path = os.path.join(OUT_PNG, name + ".png")
used = convert_to_png(svg_path, png_path, size=32)
if used:
converter_used = used
n_png += 1
print(" OK {:<24}{}".format(name, label))
except Exception as ex:
n_fail.append((name, str(ex)))
print(" FAIL {:<24}{} ({})".format(name, label, ex))
print("")
print("[icons] SVGs: {} ok / {} fail".format(n_ok, len(n_fail)))
if n_png:
print("[icons] PNGs: {} via {}".format(n_png, converter_used))
elif n_ok:
print("[icons] PNG-Konvertierung uebersprungen — kein rsvg-convert/qlmanage gefunden.")
print(" Installiere via: brew install librsvg")
if n_fail:
print("")
print("[icons] Fehlgeschlagene Icons (vielleicht andere Namen im Symbols-Repo):")
for n, err in n_fail:
print(" - {} : {}".format(n, err))
if __name__ == "__main__":
main()