Files
dxfmakros/Lisp/purge_blocks.lsp
T

226 lines
7.7 KiB
Common Lisp

;; ============================================================
;; purge_blocks.lsp
;; Entfernt in allen DWG-Dateien in data/ils die nicht
;; verwendeten Block-Definitionen und Layer (-PURGE Blocks/Layer).
;;
;; Ablauf je DWG:
;; - Datei oeffnen (falls noetig)
;; - Block- und Layer-Anzahl zaehlen
;; - -PURGE Blocks und -PURGE Layer in einer Schleife ausfuehren,
;; bis nichts mehr entfernt wird (verschachtelte Bloecke bzw.
;; nur von entfernten Bloecken benutzte Layer werden erst nach
;; dem ersten Durchlauf frei)
;; - nur speichern, wenn sich die Anzahl verringert hat
;; - schliessen (falls durch dieses Skript geoeffnet)
;;
;; Es werden AUSSCHLIESSLICH unbenutzte Bloecke und Layer entfernt.
;; Andere Objekttypen (Linientypen, Textstile, ...) bleiben
;; unangetastet.
;;
;; Voraussetzung: DXFM_DATA ist gesetzt (siehe bin/setenv.bat).
;;
;; Aufruf in BricsCAD:
;; (load "C:/.../Lisp/purge_blocks.lsp")
;; ILS_BLOCK_PURGE
;; ============================================================
(vl-load-com)
;; ------------------------------------------------------------
;; Bereits offenes Dokument mit gegebenem Pfad suchen (oder nil)
;; ------------------------------------------------------------
(defun pb-find-open-doc (dwg-pfad / docs anzahl i doc full treffer)
(setq docs (vla-get-Documents (vlax-get-acad-object))
anzahl (vla-get-Count docs)
i 0
treffer nil
dwg-pfad (strcase (vl-string-translate "\\" "/" dwg-pfad))
)
(while (and (< i anzahl) (not treffer))
(setq doc (vla-item docs i))
(setq full (strcase (vl-string-translate "\\" "/" (vla-get-FullName doc))))
(if (= full dwg-pfad) (setq treffer doc))
(setq i (1+ i))
)
treffer
)
;; ------------------------------------------------------------
;; Anzahl aller Eintraege einer Symboltabelle zaehlen
;; (z.B. "BLOCK" inkl. Model/Paper-Space/anonyme, "LAYER").
;; ------------------------------------------------------------
(defun pb-count-table (tabelle / n def)
(setq n 0 def (tblnext tabelle T))
(while def
(setq n (1+ n))
(setq def (tblnext tabelle))
)
n
)
;; ------------------------------------------------------------
;; Im aktiven Dokument unbenutzte Bloecke UND Layer purgen, bis
;; stabil. Erst Bloecke, dann Layer (ein nur von einem entfernten
;; Block benutzter Layer wird erst danach frei) - daher Schleife
;; ueber beide Typen, bis sich nichts mehr aendert.
;; ------------------------------------------------------------
(defun pb-purge-current-doc ( / vorher aktuell durchlauf max-durchlauf)
(setq vorher (+ (pb-count-table "BLOCK") (pb-count-table "LAYER"))
aktuell vorher
durchlauf 1
max-durchlauf 20
)
(while (and (<= durchlauf max-durchlauf)
(progn
(command "_.-PURGE" "_B" "*" "_N") ; unbenutzte Bloecke
(command "_.-PURGE" "_LA" "*" "_N") ; unbenutzte Layer
(setq aktuell (+ (pb-count-table "BLOCK") (pb-count-table "LAYER")))
;; weiter, solange noch etwas entfernt wurde
(if (< aktuell vorher)
(progn (setq vorher aktuell) T)
nil
)
)
)
(setq durchlauf (1+ durchlauf))
)
aktuell
)
;; ------------------------------------------------------------
;; Eine DWG-Datei oeffnen (falls noetig), purgen, speichern (nur
;; bei Aenderung) und schliessen (falls hier geoeffnet).
;; Rueckgabe: ('ok blk-entfernt . lay-entfernt) oder ('fehler . meldung)
;; ------------------------------------------------------------
(defun pb-purge-dwg (dwg-pfad / bereits-offen blk-vor blk-nach lay-vor lay-nach
blk-entfernt lay-entfernt fehler)
(setq bereits-offen (pb-find-open-doc dwg-pfad))
(setq blk-entfernt 0 lay-entfernt 0)
(setq fehler
(vl-catch-all-apply
(function
(lambda ()
(if bereits-offen
(vlax-put-property (vlax-get-acad-object) 'ActiveDocument bereits-offen)
(command "_.OPEN" dwg-pfad)
)
(setq blk-vor (pb-count-table "BLOCK")
lay-vor (pb-count-table "LAYER")
)
(pb-purge-current-doc)
(setq blk-nach (pb-count-table "BLOCK")
lay-nach (pb-count-table "LAYER")
blk-entfernt (- blk-vor blk-nach)
lay-entfernt (- lay-vor lay-nach)
)
(if (or (> blk-entfernt 0) (> lay-entfernt 0))
(command "_.QSAVE")
)
(if (not bereits-offen) (command "_.CLOSE"))
)
)
nil
)
)
(if (vl-catch-all-error-p fehler)
(cons 'fehler (vl-catch-all-error-message fehler))
(list 'ok blk-entfernt lay-entfernt)
)
)
;; ------------------------------------------------------------
;; Hauptbefehl - verarbeitet DXFM_DATA/ils
;; ------------------------------------------------------------
(defun c:ILS_BLOCK_PURGE ( / data-dir dwg-dir dateien datei dwg-pfad ergebnis
orig-doc anzahl-ok anzahl-fehler summe-blk summe-lay
blk lay fehler-liste geaendert-liste)
(setq data-dir (getenv "DXFM_DATA"))
(if (not data-dir)
(progn
(alert "DXFM_DATA ist nicht gesetzt.\nBitte zuerst bin/setenv.bat ausfuehren.")
(exit)
)
)
(setq data-dir (vl-string-translate "\\" "/" data-dir)
dwg-dir (vl-string-right-trim "/" (strcat data-dir "/ils"))
)
(if (not (findfile dwg-dir))
(progn
(princ (strcat "\n[BLOCK-PURGE] Verzeichnis nicht gefunden: " dwg-dir))
(exit)
)
)
(setq dateien (vl-directory-files dwg-dir "*.dwg" 1))
(if (not dateien)
(progn
(princ (strcat "\n[BLOCK-PURGE] Keine DWG-Dateien in: " dwg-dir))
(exit)
)
)
(setq orig-doc (vla-get-ActiveDocument (vlax-get-acad-object))
anzahl-ok 0
anzahl-fehler 0
summe-blk 0
summe-lay 0
fehler-liste nil
geaendert-liste nil
)
(foreach datei dateien
(setq dwg-pfad (strcat dwg-dir "/" datei))
(princ (strcat "\n[BLOCK-PURGE] Bearbeite " datei " ..."))
(setq ergebnis (pb-purge-dwg dwg-pfad))
(if (equal (car ergebnis) 'fehler)
(progn
(princ (strcat "\n[BLOCK-PURGE] FEHLER bei " datei ": " (cdr ergebnis)))
(setq anzahl-fehler (1+ anzahl-fehler))
(setq fehler-liste (cons datei fehler-liste))
)
(progn
(setq anzahl-ok (1+ anzahl-ok)
blk (nth 1 ergebnis)
lay (nth 2 ergebnis)
)
(if (or (> blk 0) (> lay 0))
(progn
(princ (strcat " " (itoa blk) " Block(e), " (itoa lay) " Layer entfernt, gespeichert."))
(setq summe-blk (+ summe-blk blk)
summe-lay (+ summe-lay lay)
)
(setq geaendert-liste (cons (strcat datei " (B:" (itoa blk) " L:" (itoa lay) ")") geaendert-liste))
)
(princ " keine unbenutzten Bloecke/Layer.")
)
)
)
)
(vlax-put-property (vlax-get-acad-object) 'ActiveDocument orig-doc)
(princ (strcat "\n[BLOCK-PURGE] Fertig: " (itoa anzahl-ok) " Datei(en) bearbeitet, "
(itoa summe-blk) " Block(e), "
(itoa summe-lay) " Layer entfernt, "
(itoa anzahl-fehler) " Fehler."))
(if geaendert-liste
(progn
(princ "\n[BLOCK-PURGE] Geaenderte Dateien:")
(foreach datei (reverse geaendert-liste)
(princ (strcat "\n - " datei))
)
)
)
(if fehler-liste
(progn
(princ "\n[BLOCK-PURGE] WARNUNG: Fehler bei:")
(foreach datei (reverse fehler-liste)
(princ (strcat "\n - " datei))
)
)
)
(princ)
)
(princ "\npurge_blocks.lsp geladen. Befehl: ILS_BLOCK_PURGE")
(princ)