Protéger vos blocs avec AutoLISP !

Bonjour, un nouvel exemple de petite routine générée par l’intelligence artificielle qui va vous permettre en cliquant sur une instance de bloc de la transformer en bloc anonyme de type MINSERT et donc de la protéger des utilisateurs peu curieux :smiley: ou peu versés dans la programmation, contre la décomposition et la redéfinition.

[!Note]
Une tentative est faite pour purger le bloc original.

GlobalLockClean.lsp (4,9 Ko)

;;; Généré par l'assistant AutoCAD expert IA https://dessein-tech.com/t/lassistant-expert-autocad-ia-pro-est-disponible-publiquement/9335

(defun c:GlobalLockClean (/ sourceSel sourceEnt sourceObj sourceName doc blks sourceDef newBlkDef newBlkName objList sourceArray ss i entObj pt lay rot sx sy sz ownerID ownerObj newMInsert count ans)
  (vl-load-com)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (setq blks (vla-get-blocks doc))

  ;; 1. Sélection
  (if (setq sourceSel (entsel "\nSélectionnez le bloc modèle à sécuriser : "))
    (progn
      (setq sourceEnt (car sourceSel))
      (setq sourceObj (vlax-ename->vla-object sourceEnt))

      (if (= (vla-get-objectname sourceObj) "AcDbBlockReference")
        (progn
          (setq sourceName (vla-get-name sourceObj))
          (setq sourceDef (vla-item blks sourceName)) ;; Accès à la définition du bloc source
          
          ;; 2. Création du conteneur Anonyme
          (setq newBlkDef (vla-add blks (vlax-3d-point '(0 0 0)) "*U"))
          
          ;; 3. CLONAGE DES OBJETS (La clé du succès)
          ;; On collecte tous les objets graphiques du bloc source
          (setq objList '())
          (vlax-for obj sourceDef
            (setq objList (cons obj objList))
          )
          
          ;; Si le bloc n'est pas vide
          (if objList
            (progn
              ;; Conversion de la liste Lisp en Tableau ActiveX (SafeArray)
              (setq sourceArray (vlax-make-safearray vlax-vbObject (cons 0 (1- (length objList)))))
              (vlax-safearray-fill sourceArray objList)
              
              ;; Copie directe des objets vers le nouveau bloc (Sans créer de référence !)
              (vla-CopyObjects doc sourceArray newBlkDef)
              
              (setq newBlkName (vla-get-name newBlkDef))
              (princ (strcat "\nGéométrie clonée dans : " newBlkName ". Remplacement en cours..."))

              ;; 4. Remplacement Global
              (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 sourceName))))

              (if ss
                (progn
                  (setq count (sslength ss))
                  (setq i 0)
                  (vla-StartUndoMark doc)
                  
                  (repeat count
                    (setq entObj (vlax-ename->vla-object (ssname ss i)))
                    (setq pt  (vla-get-insertionpoint entObj))
                    (setq lay (vla-get-layer entObj))
                    (setq rot (vla-get-rotation entObj))
                    (setq sx  (vla-get-xscalefactor entObj))
                    (setq sy  (vla-get-yscalefactor entObj))
                    (setq sz  (vla-get-zscalefactor entObj))
                    (setq ownerID (vla-get-OwnerID entObj))
                    (setq ownerObj (vla-ObjectIdToObject doc ownerID))

                    ;; Création MINSERT
                    (setq newMInsert (vla-AddMInsertBlock ownerObj pt newBlkName sx sy sz rot 1 1 0.0 0.0))
                    (vla-put-layer newMInsert lay)
                    
                    ;; Suppression instance originale
                    (vla-delete entObj)
                    (setq i (1+ i))
                  )
                  
                  (princ (strcat "\n" (itoa count) " instances remplacées."))

                  ;; 5. PURGE
                  (initget "Oui Non")
                  (setq ans (getkword "\nVoulez-vous PURGER la définition originale ? [Oui/Non] <Non>: "))
                  
                  (if (= ans "Oui")
                    (progn
                      (setvar "CMDECHO" 0)
                      ;; Cette fois, le bloc original n'est lié à RIEN. La purge doit passer.
                      (command "_.PURGE" "_B" sourceName "_N")
                      (setvar "CMDECHO" 1)
                      
                      (if (tblsearch "BLOCK" sourceName)
                        (alert "La purge a échoué.\nLe bloc est encore utilisé quelque part (peut-être imbriqué dans un AUTRE bloc que nous n'avons pas touché).")
                        (princ (strcat "\nSuccès total ! Le bloc '" sourceName "' a été éradiqué."))
                      )
                    )
                  )
                  (vla-EndUndoMark doc)
                )
                (princ "\nErreur : Impossible de retrouver les instances.")
              )
            )
            (princ "\nLe bloc source semble vide.")
          )
        )
        (princ "\nL'objet sélectionné n'est pas un bloc.")
      )
    )
    (princ "\nAucune sélection.")
  )
  (princ)
)
1 Like

Petite explication sur les fonctions qui commencent par « vl »:

Ces préfixes indiquent que l’on utilise les extensions Visual LISP pour accéder à la technologie ActiveX (COM) d’AutoCAD®. C’est une méthode plus moderne et souvent plus rapide que le « vieil » AutoLISP classique qui manipulait les codes DXF.

Voici la distinction entre les trois préfixes que vous verrez souvent :

  1. vl- (Visual Lisp)

Ce sont des fonctions étendues propres au langage LISP lui-même, qui n’existaient pas dans l’AutoLISP original.

  • Exemple : vl-catch-all-apply (gestion des erreurs), vl-file-copy.
  1. vla- (Visual Lisp ActiveX)

Ce sont les fonctions qui manipulent directement les objets AutoCAD® (Lignes, Calques, Présentations) via leurs propriétés et méthodes, exactement comme on le ferait en VBA ou en .NET.

  • Exemple : vla-delete correspond à la méthode « Delete » d’un objet. vla-get-color lit la propriété « Color ».
  1. vlax- (Visual Lisp ActiveX Extensions)

Ce sont des fonctions utilitaires nécessaires pour faire le pont entre le LISP et le moteur ActiveX (initialisation, conversion de données).

  • Exemple : vlax-get-ACAD™-object permet de « saisir » l’application AutoCAD® pour commencer à travailler.

En résumé : Au lieu de simuler des commandes clavier avec (command « _erase » …), le Visual LISP agit directement sur le moteur