Modifier l'origine de plusieurs hachures en LISP/Visual LISP

Comment modifier par lot le point d’origine de plusieurs hachures existantes à l’aide d’une routine LISP ? Mes hachures ont une origine par défaut très éloignée (proche de 0,0), ce qui cause des problèmes d’affichage. Mes tentatives avec entmod (codes DXF 43/44) ou vla-put-Origin en Visual LISP échouent avec des erreurs de type (VARIANT, SafeArray).

La modification de l’origine d’une hachure via LISP nécessite de comprendre comment AutoCAD gère les types de données, en particulier pour les points de coordonnées. Les erreurs rencontrées proviennent d’une incompatibilité entre le format de point LISP (une liste) et le format attendu par les fonctions ActiveX/VLA (un Variant de type SafeArray).

Voici la démarche experte pour résoudre ce problème, en utilisant la méthode Visual LISP (VLA), plus moderne et robuste.

Étape 1 : Diagnostic des erreurs courantes

  1. Erreur avec vla-put-Origin et un point LISP : (vla-put-Origin obj p1)p1 est '(X Y Z) échoue car la fonction attend un objet Variant (SafeArray), pas une simple liste LISP.
  2. Erreur avec vlax-3d-point : (vla-put-Origin obj (vlax-3d-point p1)) peut échouer avec une erreur « Le nombre d’éléments dans SafeArray est incorrect ». Cela se produit car la propriété Origin d’une hachure attend un point 2D (X, Y), alors que vlax-3d-point crée un tableau à 3 éléments (X, Y, Z).

Étape 2 : La solution Visual LISP correcte

La solution consiste à fournir à la propriété Origin un tableau (SafeArray) de doubles à 2 éléments. La méthode la plus propre est de créer ce tableau manuellement.

Voici un code LISP fonctionnel et commenté qui applique cette solution :

;; Fonction pour convertir un point LISP 2D/3D en un SafeArray 2D pour les hachures
(defun list->safearray-2d (pt / sa)
  (setq sa (vlax-make-safearray vlax-vbDouble '(0 . 1))) ; Crée un tableau pour 2 doubles
  (vlax-safearray-fill sa (list (car pt) (cadr pt)))     ; Remplit le tableau avec X et Y
  sa                                                      ; Retourne le SafeArray
)

;; Commande principale pour modifier l'origine des hachures sélectionnées
(defun c:HatchOriginReset ( / *error* doc ss i ent vla-obj new-origin)

  ;; Gestionnaire d'erreur local pour restaurer le système
  (defun *error* (msg)
    (if (and doc (not (vlax-object-released-p doc)))
      (vla-endundomark doc)
    )
    (cond
      ((not msg))
      ((wcmatch (strcase msg) "*QUIT*,*CANCEL*"))
      (t (princ (strcat "\nErreur: " msg)))
    )
    (princ)
  )

  (vl-load-com) ; S'assurer que les fonctions VLA sont chargées

  (setq doc (vla-get-activedocument (vlax-get-acad-object)))

  (princ "\nSélectionnez les hachures à modifier : ")
  (if (setq ss (ssget '((0 . "HATCH"))))
    (if (setq new-origin (getpoint "\nSpécifiez le nouveau point d'origine : "))
      (progn
        (vla-startundomark doc) ; Début du marqueur d'annulation
        (setq i -1)
        (repeat (sslength ss)
          (setq ent (ssname ss (setq i (1+ i))))
          (setq vla-obj (vlax-ename->vla-object ent))
          
          ;; Application de la nouvelle origine via la propriété ActiveX
          ;; en utilisant notre fonction de conversion
          (vla-put-Origin vla-obj (list->safearray-2d new-origin))

          ;; Alternative plus concise (mais moins explicite) qui fonctionne souvent :
          ;; (vlax-put vla-obj 'Origin (list (car new-origin) (cadr new-origin)))

          (vla-update vla-obj) ; Forcer la mise à jour graphique de l'objet
        )
        (vla-endundomark doc) ; Fin du marqueur d'annulation
        (princ (strcat "\n" (itoa (sslength ss)) " hachure(s) mise(s) à jour."))
      )
      (princ "\nOpération annulée.")
    )
    (princ "\nAucune hachure sélectionnée.")
  )
  (princ)
)

Étape 3 : Alternative via les variables système (sans programmation)

Pour les futures hachures, il est recommandé de configurer correctement les variables système d’AutoCAD pour éviter ce problème :

  1. Tapez la commande HPORIGINMODE.
  2. Réglez sa valeur à 1 (Utiliser un nouveau point d’origine).
  3. Tapez la commande HPORIGIN.
  4. Cliquez sur un point proche de votre zone de travail. Ce point servira d’origine par défaut pour toutes les nouvelles hachures, assurant leur cohérence.

Cette méthode préventive, combinée à la routine LISP pour corriger l’existant, offre une solution complète.