(gile) Posté(e) le 20 février 2011 Partager Posté(e) le 20 février 2011 Salut, Suite à ce sujet, je propose 3 petites routines qui utilisent les codes de groupes 331 des données DXF des objets BLOCK_RECORD (AcDbBlockTableRecord), autrement dit les définitions de bloc. gc:IsReferenced : Évalue s'il existe des références du bloc non effacées (dans le dessin ou dans un bloc). Retourne T ou nil ;; gc:IsReferenced ;; Evalue si le bloc est référencé ;; ;; Argument ;; bname : nom du bloc (defun gc:IsReferenced (bname / blk blkRec blkRefs) (and (setq blk (tblobjname "BLOCK" bname)) (setq blkRec (cdr (assoc 330 (entget blk)))) (setq blkRefs (vl-remove nil (mapcar 'entget (gc:massoc 331 (entget blkRec))))) (vl-some 'vl-consp (mapcar '(lambda (x) (entget (cdr (assoc 330 x)))) blkRefs)) ) ) gc:PurgeBlock Purge les blocs (même imbriqués) dont le nom correspond au modèle.Le modèle accepte les caractères génériques et n'est pas sensible à la casse.Exemple : (gc:PurgeBlock "*") purge tous les blocs. ;; gc:PurgeBlock ;; Purge les blocs dont le nom correspond au modèle (insensible à la casse) ;; ;; Argument ;; pat : un modèle pour le nom de bloc, accepte les caractères génériques ("*" pour tous) (defun gc:PurgeBlock (pat / blk name blst loop) (vl-load-com) (while (setq blk (tblnext "BLOCK" (not blk))) (if (and (wcmatch (strcase (setq name (cdr (assoc 2 blk)))) (strcase pat)) (< (cdr (assoc 70 (setq elst (entget (tblobjname "BLOCK" name))))) 4) ) (setq blst (cons (cdr (assoc 330 elst)) blst)) ) ) (setq loop T) (while (and loop blst) (setq loop nil) (foreach b blst (or (vl-some 'entget (gc:massoc 331 (entget b))) (progn (setq blk (vlax-ename->vla-object b)) (vlax-for o blk (if (= (vla-get-ObjectName o) "AcDbBlockReference") (vla-Delete o) ) ) (vla-delete blk) (setq blst (vl-remove b blst)) (setq loop T) ) ) ) ) ) gc:GetReferences Retourne la liste des références du bloc insérées dans le dessin et/ou imbriqués dans des blocs en fonction de la valeur du 'drapeau'.Cette routine peut avantageusement remplacer un (ssget "_X" ...) pour obtenir toutes les références d'un bloc dans le dessin. Exemple avec un dessin contenant 17853 entités dont 29 références du bloc "poste-ria" :_$ (benchmark '((ssget "_x" '((0 . "INSERT") (2 . "poste-ria")))(gc:GetReferences "poste-ria" 2)))Benchmarking .............Elapsed milliseconds / relative speed for 1024 iteration(s): (GC:GETREFERENCES "poste-ria" 2)..............1170 / 16.17 (SSGET "_x" (QUOTE ((0 . "INSERT") (...).....18922 / 1 ;; gc:GetReferences ;; Retourne la liste des références de bloc non effacées ;; ;; Arguments ;; bname : nom du bloc ;; flag : drapeau (somme des codes binaires suivants ;; 1 = imbriqués dans des blocs ;; 2 = insérés dans l'espace objet ;; 4 = insérés dans un espace papier (defun gc:GetReferences (bname flag / blk refs elst) (if (and (setq blk (tblobjname "BLOCK" bname)) (setq refs (vl-remove-if-not 'cdr (mapcar (function (lambda (x) (if (setq elst (entget x)) (cons x (entget (cdr (assoc 330 elst)))) ) ) ) (gc:massoc 331 (entget (cdr (assoc 330 (entget blk))))) ) ) ) ) (if (= 7 flag) (mapcar 'car refs) (if (< 0 flag 7) (mapcar 'car (vl-remove-if (function (lambda (x) (wcmatch (strcase (cdr (assoc 2 (cdr x)))) (cond ((= 1 flag) "`**_SPACE*") ((= 2 flag) "~`*MODEL_SPACE") ((= 3 flag) "`*PAPER_SPACE*") ((= 4 flag) "~`*PAPER_SPACE*") ((= 5 flag) "`*MODEL_SPACE*") ((= 6 flag) "~`**_SPACE*") ) ) ) ) refs ) ) ) ) ) ) Ces routines utilisent gc:massoc;; gc:massoc ;; Retourne la liste de toutes les valeurs pour le code spécifié dans une liste d'association ;; ;; Arguments ;; code : la clé recherchée (code de groupe pour les listes DXF) ;; alst : la liste d'association (defun gc:massoc (code alst) (if (setq alst (member (assoc code alst) alst)) (cons (cdar alst) (gc:massoc code (cdr alst))) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
bryce Posté(e) le 20 février 2011 Partager Posté(e) le 20 février 2011 La différence de performances entre ssget et GetReferences est impressionnante... :exclam:Merci pour le partage ! Brice, formateur AutoCAD - Inventor - SolidWorks - ZWCad - DraftSight - SketchUp indépendant Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 20 février 2011 Auteur Partager Posté(e) le 20 février 2011 La différence de performances entre ssget et GetReferences est impressionnante... :exclam: Elle le sera d'autant plus que le dessin comportera beaucoup d'entités et peu (ou pas) de références de bloc. Un (ssget "X" ...) doit parcourir tout le dessin pour filtrer les entités et un jeu de sélection est un objet plus complexe qu'une liste de ENAMEs (il contient aussi des informations sur la façon dont a été faite la sélection).La différence de performances devrait encore être un peu augmentée si on parcourt le jeu de sélection ce qui est plus couteux que de parcourir une liste. Mais il faut relativiser tout ça, dans l'exemple ci-dessus une sélection est faite en environ 18 millisecondes quand gc:GetReferences crée une liste en un peu plus d'une milliseconde la différence sera probablement impalpable pour l'utilisateur. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant