Handle_explorer : Explorer votre dessin en parcourant les identifiants
Cet article s’adresse aux programmeurs Autocad en herbe ou confirmés, qu’ils programment en Lisp en VBA ou en .Net
Problématique.
Il arrive parfois que l’on ait un besoin de développement avec des entités non documentées, ou un problème avec un dessin, ou un contrôle de dessin qui affiche des erreurs auxquelles on ne comprend rien.
Par exemple, le message « xdata problem, fix or remove » et le message « entité en propriété multiple »
A chaque fois, Autocad nous donne le maintien (identifiant) de l’entité.
Parfois, la facétie d’Autocad fait que cette entité est une sous entité d’un bloc, d’un dictionnaire d’extension, ou d’un xrecord…
Dans ce cas-là, trouver l’origine du problème peut être très long…
C’est là qu’handle explorer intervient : parcourir les entités propriétaires et les sous-entités d’une entité.
Il existe, en VBA et sous visual lisp, des possibilités d’explorer les entités : Le problème, en VBA, c’est que la forme d’affichage n’est pas très parlante, et dans les 2 systèmes, on a pas accès aux valeurs qui sont lues et écrites par des méthodes.
Et pour les entités issues d’applications tierces, vous n’aurez rien à vous mettre sous la dent.
Handle_explorer je l’ai créé en 2007 pour percer le mystère des filtres de propriétés de calques en cascade, car leur emplacement n’était pas documenté par Autodesk.
Pré-requis :
Avoir PowerClic installé et fonctionnel, pour que les fonctions commençant par PW_ soient chargées.
Connaître au moins un peu le lisp, et connaître un peu la structure DXF.
Principe :
Handle_explorer vous demande le maintien d’une entité, ou part de l’objet « Dictionaries », qui est un peu le point de départ d’une bonne exploration.
Chaque fois qu’handle explorer trouve un renvoi vers une autre entité, il vous demande si vous voulez l’explorer.
Pour changer d’entité, il faut copier le maintien qui vous intéresse, et relancer handle_explorer avec le nouvel identifiant.
Une amélioration qui serait nécessaire, c’est l’affichage de l’arborescence de l’exploration, et le changement d’entité automatique : ça viendra peut-être …
Exemple :
Commande: HANDLE_EXPLORER
Commencer l'exploration par AcadDictionaries ?Oui/Non :O
Maintien de l'entité ? :
(-1 . )
(0 . "DICTIONARY")
(330 . 0>)
(5 . "C")
(100 . "AcDbDictionary")
(280 . 0)
(281 . 1)
(3 . "ACAD_COLOR")
(350 . )
(3 . "ACAD_GROUP")
(350 . )
(3 . "ACAD_IMAGE_VARS")
(350 . )
(3 . "ACAD_LAYOUT")
(350 . )
(3 . "ACAD_MATERIAL")
(350 . )
(3 . "ACAD_MLEADERSTYLE")
(350 . )
(3 . "ACAD_MLINESTYLE")
(350 . )
(3 . "ACAD_PLOTSETTINGS")
(350 . )
(3 . "ACAD_PLOTSTYLENAME")
(350 . )
(3 . "ACAD_SCALELIST")
(350 . )
(3 . "ACAD_TABLESTYLE")
(350 . )
(3 . "ACAD_VISUALSTYLE")
(350 . )
(3 . "AcDbVariableDictionary")
(350 . )
(3 . "Root")
(350 . )
(3 . "{24DE2741-47F6-4298-B91B-737E814BAE3E}")
(350 .
)
- * - * - * - * - * - * - * - * - * - * - * - * - *
Entité sans entget: ename = 0
Code 350 trouvé: 6B Afficher l'entget entité ?Oui/Non :
Etiquette associée à l'entité : (3 . "ACAD_COLOR")
(-1 . )
(0 . DICTIONARY)
(5 . 6B)
(102 . {ACAD_REACTORS)
(330 . )
(102 . })
(330 .
)
(100 . AcDbDictionary)
(280 . 0)
(281 . 1)
- - - - - - - - - - - - - -
Code 350 trouvé: D Afficher l'entget entité ?Oui/Non :n
Code 350 trouvé: 218
Afficher l'>entget entité ?Oui/Non :
Code 350 trouvé: 1A
Afficher l'>entget entité ?Oui/Non :
Code 350 trouvé: 6A
Afficher l'>entget entité ?Oui/Non :
Code 350 trouvé: 12D
Afficher l'>entget entité ?Oui/Non :*Annuler*
Un petit coup d‘echap pour arrêter : on veut explorer acad_color, on prend le maintien « 6B »
Commande: HANDLE_EXPLORER
Maintien de l'entité ? :6B
(-1 . )
(0 . "DICTIONARY")
(5 . "6B")
(102 . "{ACAD_REACTORS")
(330 . )
(102 . "}")
(330 .
)
(100 . "AcDbDictionary")
(280 . 0)
(281 . 1)
- * - * - * - * - * - * - * - * - * - * - * - * - *
Code 330 trouvé: C Afficher l'entget entité ?Oui/Non :n
Code 330 trouvé: C
Afficher l'>entget entité ?Oui/Non :
Le dessin est vide, le dictionnaire acad_color n’a pas d’enfant, seulement un propriétaire, « C », que l’on connaît déjà : l’exploration est terminée.
Procédure
Placer le code qui suit dans un fichier lisp,(extension .lsp), charger le fichier (un drag'n drop marche très bien), et lancer la commande handle_explorer
Début du code :
; ****************************************************************************
;;§/dxf/Exploration autour d'un handle vers les entités présentes
/none
;;les code rechercés sont 330 331 340 345 346 347 348 349 350 360 390
;;;330 ID/identificateur pointeur logiciel du dictionnaire propriétaire (facultatif)
;;;
;;;360 ID/identificateur de propriétés matérielles du dictionnaire propriétaire (facultatif)
;;;
;;;330 ID/identificateur pointeur logiciel de l'objet propriétaire
;;;
;;;350 ID/identificateur propriétaire logiciel de l'objet entrée (un pour chaque entrée) (facultatif)
;;autres codes :
;;;331 ID/identificateur de la dernière fenêtre active dans la présentation lorsque celle-ci était la présentation courante.
;;;
;;;345 ID/identificateur de l'énumération AcDbUCSTableRecord s'il s'agit d'un SCU nommé. En cas d'absence, le SCU n'est pas
nommé
;;;
;;;346 ID/identificateur de l'énumération AcDbUCSTableRecord du SCU de base s'il s'agit d'un SCU
orthogonal (code 76 différent de 0). En cas d'absence et si le code 76 est différent de 0, le SCU de base est du type GENERAL
(defun c:handle_explorer (/ eg i cont eg2 dxf id prec)
(if (not HDE-ident)
(if (= "Oui"
(pw_getkwordmem
"\nCommencer l'exploration par AcadDictionaries ?/Oui Non"
"HDE-App"
)
)
(setq
HDE-ident (vla-get-handle
(vla-get-dictionaries
(vla-get-ActiveDocument (vlax-get-acad-object))
)
)
)
)
)
(pw_getstringmem "\nMaintien de l'entité ?"
"HDE-ident")
(setq eg (entget (handent HDE-ident)))
(foreach l eg
(print l)
)
(prompt
"\n - * - * - * - * - * - * - * - * - * - * - * - * - *"
)
(setq i 0
cont "Oui"
)
(setq prec "")
(while (setq dxf (nth i eg))
(if (member (car dxf)
'(330 331 340 345 346 347 348 349 350 360 390)
)
(if (setq eg2 (entget (cdr dxf)))
(progn (setq id (cdr (assoc 5 eg2)))
(prompt
(strcat
"\n Code " (itoa
(car dxf)) " trouvé: "
id " ")
)
(prin1 (cdr dxf))
(pw_getkwordmem
"\nAfficher
l'entget entité ?/Oui Non"
"cont"
)
(if (= "Oui" cont)
(progn
(prompt (strcat "\n Etiquette associée à l'entité : "
(pw_fab_chaine prec)
)
)
(foreach l eg2
(prompt "\n ")
(princ l)
)
(prompt "\n- - - - - - - - - - - - - -")
)
)
)
(prompt "\nEntité sans entget: ename = 0")
)
)
(setq prec dxf)
(setq i (+ 1 i))
)
)