-
Compteur de contenus
12 247 -
Inscription
-
Dernière visite
-
Jours gagnés
209
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par (gile)
-
Je ne vois pas bien, chez moi çà marche, la seule chose : certaines variables n'étaient pas déclarées, peut-être restait-il des éléments dans une des listes alors qu'il avaient été purgés ? J'ai modifié le code en déclarant bien toutes les variables. Si tu ré-essayes dans le même dessin avec la nouvelle mouture, fais : (foreach n '(AcDoc ss n lst obj name bloc ent r_lst p_lst c_lst m) (set n nil) ) avant de lancer la routine, pour assurer le coup. Sinon, si tu pouvais faire d'abord raster_purge puis xref_purge et ensuite seulement spurge on pourrais localiser l'erreur. [Edité le 12/6/2006 par (gile)]
-
Avec la dernière version ? As tu le même problème avec la précédente ? ou bien le problème vient-il de raster_purge ou xref_purge ?
-
Merci Patrick_35 pour le lien, je verrais çà ce soir, on dirait que c'est pas près d'être fini cette histoire de "super purge" ! Sinon, j'ai réparé (enfin, j'espère) la routine qui purge tous les blocs (même imbriqués) en une seule fois.
-
Salut, dézoome un peu ou fais glisser la carte, tu verras la "fin de la terre".
-
Encore un fois je suis allé un peu vite en besogne, la version de SPURGE juste au dessus contenait une erreur ! Je modifie le code. Toutes mes excuses à ceux qui auront testé et se seront retrouvé dans une boucle sans fin :calim: EDIT : La réparation est plus complexe que prévu, le code ci dessus est supprimé momentanément, on peut utiliser celui donné plus haut (qui ne purge pas toutes les imbrications de blocs)[Edité le 12/6/2006 par (gile)] EDIT 2 : Cette fois, je pens que c'est bon ! [Edité le 12/6/2006 par (gile)]
-
Problemme d\'echelle entre espace objet et papier
(gile) a répondu à un(e) sujet de beeshop dans AutoCAD 2006
Salut, À priori, dans AutoCAD, on travaille à l'échelle 1 suivant l'unité qu'on a choisi (si on travaille en mètres 1 m = 1 unité, si on travaile en millimètres 1 mm = 1 unité). Tu peux voir ce sujet. La question de l'échelle se pose au moment de la mise en page (espace papier), pour l'échelle des types de ligne, tu peux voir ce sujet, pour la cotation, il y a plusieurs écoles, qui font parfois l'objet de discussions animées, voir ici ou bien ici ou encore là, tu peux aussi voir l'aide Manuel d'utilisation -> Hachures, notes, tableaux et cotes -> Cotes et tolérances -> Utilisation des styles de cote -> Définition de l'échelle des cotes. -
Une amélioration pour SPURGE, pour purger complètement les blocs imbriqués (version corrigée le 13/06/06) : VERSION 1.0 ;;; SPURGE Purge tout, y compris les blocs imbriqués, les xrefs et les images non référencées (defun c:spurge (/ AcDoc ss n obj name bloc ent r_lst x_lst p_lst c_lst m) (vl-load-com) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;; Purge les xrefs et rasters non référencées (c:xref_purge) (c:raster_purge) ;; r_lst : liste des blocs et "sous-blocs" insérés ;; x_lst : liste des xrefs insérées (setq ss (ssget "_X" '((0 . "INSERT")))) (if ss (progn (repeat (setq n (sslength ss)) (setq obj (vlax-ename->vla-object (ssname ss (setq n (1- n)))) ) (if (vlax-property-available-p obj 'EffectiveName) (setq name (vla-get-EffectiveName obj)) (setq name (vla-get-Name obj)) ) (if (= :vlax-true (vla-get-isXref (vla-item (vla-get-Blocks AcDoc) name) ) ) (if (not (member name x_lst)) (setq x_lst (cons name x_lst)) ) (if (not (member name r_lst)) (setq r_lst (cons name r_lst)) ) ) ) ;; Ajout des "sous-blocs" des blocs insérés à r_lst (setq n 0) (if r_lst (while (setq name (nth n r_lst)) (setq bloc (vla-item (vla-get-blocks acDoc) name)) (repeat (setq m (vla-get-count bloc)) (setq ent (vla-item bloc (setq m (1- m)))) (if (and (= (vla-get-ObjectName ent) "AcDbBlockReference") (not (member (vla-get-name ent) r_lst)) ) (setq r_lst (reverse (cons (vla-get-Name ent) (reverse r_lst))) ) ) ) (setq n (1+ n)) ) ) ) ) (setq p_lst T) (while p_lst (vla-PurgeAll AcDoc) ;; c_lst liste des définitions de blocs de la collection (setq c_lst nil) (repeat (setq n (vla-get-count (vla-get-blocks AcDoc))) (setq c_lst (cons (vla-get-name (vla-item (vla-get-blocks AcDoc) (setq n (1- n))) ) c_lst ) ) ) ;; p_lst : liste des blocs à purger, soit les blocs de la collection ... ;; ... moins les blocs "*Model_Space" "*Paper_Space*" et les blocs insérées (setq p_lst (vl-remove-if '(lambda (x) (or (= (substr x 1 1) "*") (member x r_lst) ) ) c_lst ) ) ;; ... moins les xrefs insérées et les blocs qu'elles contiennent (mapcar '(lambda (x) (setq p_lst (vl-remove-if '(lambda (y) (wcmatch y (strcat x "*")) ) p_lst ) ) ) x_lst ) ) (vla-AuditInfo AcDoc :vlax-true) (princ) )[Edité le 12/6/2006 par (gile)][Edité le 12/6/2006 par (gile)][Edité le 13/6/2006 par (gile)][Edité le 13/6/2006 par (gile)] [Edité le 13/6/2006 par (gile)]
-
Ce pourrait être le nouveau jeu de la semaine
(gile) a répondu à un(e) sujet de esbe dans AutoCAD 2005
La commande editref demande de sélectioner une référence de bloc, or Esbe parle de blocs "insélectionnables". Avec l'éditeur de bloc 2006/2007 on choisit le bloc à modifier dans une liste de la boite de dialogue (liste qui contient tous les blocs de la collection de dessin). -
Ce pourrait être le nouveau jeu de la semaine
(gile) a répondu à un(e) sujet de esbe dans AutoCAD 2005
Si tu peux avoir accès à une version 2006 ou 2007, il y a dans ces versions un "Éditeur de blocs" dans lequel on fait les blocs dynamiques, mais qui peut servir aussi à modifier des blocs non dynamiques. Menu Outils -> Editeur de blocs On choisit le bloc dans la liste de la boite de dialogue et un fenêtre s'ouvre avec le bloc "explosé" on fait les modifications, on enregistre le bloc et on referme (comme il s'agit de la définition du bloc le point d'insertion est en 0,0). -
Ce pourrait être le nouveau jeu de la semaine
(gile) a répondu à un(e) sujet de esbe dans AutoCAD 2005
salut Esbe, Tu peux effectivement utiliser Edit_bloc directement dans le dessin incriminé pour modifier les définitions de blocs du dessin. Si tu veux faire un wbloc pour chaque bloc du dessin et modifier ensuite tous ces wbloc : - tu crées un nouveau dossier - tu lances WBLOCM (le LISP donné par lecrabe) en indiquant le chemin du nouveau dossier. - tu lances Edit_bloc_rep en choisissant un fichier dans le nouveau dossier. - la boite de dialogue de "edit_bloc" permet alors de traiter en une seule fois tous le wblocs du répertoire. Je ne garantis pas le résultat avec la seconde solution, "Edit_bloc_rep" est en cours d'élaboration (des erreurs en cas d'autoréférencement), surtout avec des blocs d'origine "douteuse". À noter toutefois, "Edit_bloc" ne permet pas le changement de point d'insertion, ce type de modification est à faire individuellement pour chaque bloc. Doublé par lecrabe, mais nos réponses se complètent ;) [Edité le 11/6/2006 par (gile)] -
Suite aux remarques pertinentes de sergluc (message privé) concernant "Edit_bloc_rep" (le petit dernier), j'ai ajouté des tests pour éviter de lancer la procédure dans un fichier qui ne serait pas vierge (contenant des entités et/ou des définitions de blocs), et un zoom (étendu + échelle) avant de réenregistrer le wbloc (pour l'apparence des icones).
-
Merci lecrabe, je corrige.
-
Suite à un échange avec sergeluc et en m'inspirant largement de ce qu'il avait fait pour modifier tous les wblocs d'un répertoire, j'ai fait ce LISP pour utiliser "Edit_bloc" sur tous les fichiers DWG d'un répertoire (bibliothèque de wblocs). NOTA : c'est avec ce LISP que j'ai remarqué l'oubli corrigé dans la version 2.3 (il faut donc charger cette nouvelle verion pour utiliser le LISP) Version 1.1 (11/06/06) ;;; Pour lancer Edit_bloc sur tout un répertoire de wblocs ;;; À utiliser dans un dessin vierge (brouillon) ;;; Choisir l'option "Toute la collection" (defun c:edit_bloc_rep (/ App AcDoc ModSp n lst file dir f_lst ss) (vl-load-com) (setq App (vlax-get-acad-object) AcDoc (vla-get-ActiveDocument App) ModSp (vla-get-ModelSpace acDoc) ) ;; Teste la présence d'entités graphiques dans le dessin (if (ssget "_X") (progn (alert "Le dessin contient des entités. \nCe programme doit être lancé à partir d'un dessin vierge." ) (exit) ) ) ;; Teste la présence de définitions de blocs dans le dessin (repeat (setq n (vla-get-count (vla-get-blocks AcDoc))) (setq lst (cons (vla-get-name (vla-item (vla-get-blocks AcDoc) (setq n (1- n))) ) lst ) ) ) (if (vl-remove-if '(lambda (x) (wcmatch x "*Space*")) lst) (progn (alert "Le dessin contient des définitions de blocs. \nCe programme doit être lancé à partir d'un dessin vierge." ) (exit) ) ) (setq file (getfiled "Choisir un fichier dans le répertoire à modifier" "" "dwg" 0 ) ) (if file (progn (setq dir (vl-filename-directory file) f_lst (vl-directory-files dir "*.dwg") ) (mapcar '(lambda (x) (setq bl (vla-InsertBlock ModSp (vlax-3d-point '(0 0 0)) x 1 1 1 0 ) ) (vla-erase bl) ) (mapcar '(lambda (x) (strcat dir "\\" x)) f_lst) ) (c:edit_bloc) (mapcar '(lambda (x) (setq bl (vla-InsertBlock ModSp (vlax-3d-point '(0 0 0)) (vl-string-right-trim ".DWG" (strcase x)) 1 1 1 0 ) ) (vla-ZoomExtents App) (vla-ZoomScaled App 0.9 1) (setq ss (vla-add (vla-get-SelectionSets AcDoc) "wbloc_ss")) (vla-addItems ss (vla-explode bl)) (vla-wblock AcDoc (strcat dir "\\" x) ss) (vla-erase ss) (vla-delete ss) (vla-delete (vlax-ename->vla-object (entlast))) ) f_lst ) ) ) (princ) ) [Edité le 11/6/2006 par (gile)]
-
Version 2.3 Encore une petite correction, comme quoi il faut pas être pressé, pour le mettre en téléchargement.
-
Merci sergeluc, À première vue tu n'es pas du tout hors sujet, je vais regarder çà de plus près. J'étais justement en train de chercher aussi un moyen par le biais des "dictionnaires". C'est moi qui ne suis pas sérieux, je poste un code faux en vitesse avant de partir au boulot, et c'est là que je me rends compte de ma bétise alors que je n'ai plus de moyen de corriger ! Pour Fraid, Voilà, j'ai fini par trouver quelque chose qui semble fonctionner (renommé RASTER_PURGE) : Version corrigée : les images contenues dans des blocs ne sont pas purgées ;;; RASTER_PURGE Purge les images raster non référencées (defun c:raster_purge (/ AcDoc lay l_lst im_dict n im_lst ss name) ;; Chargement des fonctions ActiveX (vl-load-com) ;; AcDoc : pointeur vers le document actif (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;; Dévérouillage de tous les calques (repeat (setq n (vla-get-count (vla-get-Layers AcDoc))) (setq lay (vla-item (vla-get-Layers AcDoc) (setq n (1- n)))) (if (= :vlax-true (vla-get-lock lay) ) (progn (vla-put-lock lay :vlax-false) (setq l_lst (cons lay l_lst)) ) ) ) ;; Recherche du "dictionnaire" des images (s'il existe) (setq im_dict (vl-catch-all-apply 'vla-item (list (vla-get-Dictionaries acdoc) "ACAD_IMAGE_DICT") ) ) (if (vl-catch-all-error-p im_dict) (setq im_dict nil) ) ;; Constitution d'une liste des images contenues dans la "bibliothèque" (if im_dict (progn (repeat (setq n (vla-get-Count im_dict)) (setq im_lst (cons (vla-item im_dict (setq n (1- n))) im_lst)) ) ;; Suppression de la liste des images insérées dans le dessin (if (setq ss (ssget "_X" '((0 . "IMAGE")))) (repeat (setq n (sslength ss)) (setq name (vla-get-Name (vlax-ename->vla-object (ssname ss (setq n (1- n)))) ) im_lst (vl-remove (vla-item im_dict name) im_lst) ) ) ) ;; Suppression de la liste des images contenues dans les blocs insérées (if (setq ss (ssget "_X" '((0 . "INSERT")))) (repeat (setq n (sslength ss)) (setq obj (vlax-ename->vla-object (ssname ss (setq n (1- n))))) (if (vlax-property-available-p obj 'EffectiveName) (setq name (vla-get-EffectiveName obj)) (setq name (vla-get-Name obj)) ) (setq bloc (vla-item (vla-get-blocks AcDoc) name)) (repeat (setq m (vla-get-count bloc)) (setq ent (vla-item bloc (setq m (1- m)))) (if (= (vla-get-ObjectName ent) "AcDbRasterImage") (setq im_lst (vl-remove (vla-item im_dict (vla-get-Name ent)) im_lst ) ) ) ) ) ) ;; Suppression du dessin des images restant dans la liste (mapcar '(lambda (x) (vl-catch-all-apply 'vla-delete (list x))) im_lst ) ) ) ;; Restauration de l'état des calques (if l_lst (mapcar '(lambda (x) (vla-put-lock x :vlax-true) ) l_lst ) ) (princ) ) On pourrait "fondre" raster_purge et xref_purge en une seule routine spurge, pour éviter les redondences (AcDoc, dévérrouillage et reverrouillage) mais il peut être intéressant d'avoir ces deux routines pour les utiliser séparément.[Edité le 10/6/2006 par (gile)] [Edité le 13/6/2006 par (gile)]
-
saisir une polyligne dans lisp
(gile) a répondu à un(e) sujet de zebulon_ dans Pour aller plus loin en LISP
Je ne suis pas sûr de bien comprendre, mais si tu veux utiliser cette routine et récupérer la liste des sommets de la poly créée : (setq p (getpoint) lst (cons p lst) ;_ le premier point est mis dans la liste ) (command "_.pline" p (while p (command (setq p (getpoint p))) (setq lst (cons p lst)) ;_ chaque nouveau point est ajouté en début de liste ) ) (setq lst (reverse (cdr lst))) ;_ la liste, sans le premier élément (nil) est remise dans l'ordre de saisie Tu peux ensuite traiter les points de la liste avec une fonction itérative. -
Merci, Je ne comprends pas tout dans le lien que tu donnes (anglais oblige), et il ne semble pas directement lié avec ce qui nous préoccupe ici. D'après ce que j'ai pu comprendre, AcadRasterImage serait le nom de la classe VBA pour les images raster, et ImageFile c'est le chemin du fichier lié (comme Path pour les xrefs). Mon souci, c'est que d'après l'aide (ActiveX and VBA Reference) il me semble qu'on ne puisse pas accéder aux images autrement que par une sélection (dans les espaces papier et objet, dans les blocs) et qu'il n'est pas spécifié non plus de méthode pour les détacher (seulement delete).
-
C'est ce que disons, si tu ne penses pas appeler la fonction directement en faisant routine à la ligne de commande, fais simplement : (defun routine (arg1 arg2 / ) ...) que tu peux ensuite appeler depuis un LISP, la ligne de commande, un menu, un bouton en faisant : (routine a b) (ou ^C^C(routine a b); pour un bouton) [Edité le 9/6/2006 par (gile)]
-
Salut, On peut, depuis un lisp appeler une routine définie par un (defun c:routine ...). On l'appelle depuis le LISP en faisant (c:routine). Ce qui est curieux dans ton exemple, c'est d'avoir un defun (c:routine (arg1 arg2 /) ...) avec des arguments. Quand on choisit de faire un (defun c:routine ...) c'est pour pouvoir appeler le LISP en tapant directement routine à la ligne de commande (ou dans un menu, une macro ...) et, dans ce cas, je vois mal comment les arguments peuvent passer à la fonction routine. Si une fonction nécessite un (ou des) argument(s) on la définit avec (defun routine (arg1 arg2 /) ...) et on l'appelle depuis un LISP (ou à la ligne de commande ou dans un menu ...) avec (routine a b) où a et b sont les arguments. Dans ton exemple, il n'est pas nécessaire de faire des (defun c:* ...) même si çà ne devrait pas poser de problème de fonctionnement.
-
Pour Fraid, Désolé ... J'ai beau chercher, je ne trouve pas où sont "stockées" ces images éffacées (pour le LISP il faut bien pouvoir comparer le "stock" avec les références toujours insérées dans le dessin), je ne trouve pas non plus d'autre moyen de les détacher que le menu contextuel du gestionnaire (pas de commande ni de fonction LISP ou Vlisp)
-
Pour sergeluc, Et pourtant il y a une erreur ! J'avais oublié de mettre l'argument pour (vl-catch-all-apply 'vla-get-Path ...) sous forme de liste. Je corrige le code.
-
Pour sergeluc, grace aux contributions de Bonuscad et Patrick_35, je fais une proposition pour remplacer l'expressin (mapcar ...) qui teste et supprime les xrefs. Çà devrait marcher avec toutes les versions (pas testé). (mapcar '(lambda (x) (if ( (if (not (open (vla-get-Path (vla-item (vla-get-blocks acdoc) x)) "r" ) ) (vla-detach (vla-item (vla-get-Blocks AcDoc) x)) ) (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-get-Path [surligneur](list[/surligneur] (vla-item (vla-get-blocks acdoc) x) [surligneur])[/surligneur] ) ) (vla-detach (vla-item (vla-get-Blocks AcDoc) x)) ) ) ) lst ) [surligneur]correction[/surligneur] [Edité le 9/6/2006 par (gile)]
-
La fonction and est renseignée, comme les autres fonctions LISP, dans l'Aide aux développeurs -> AutoLISP Reference -> AutoLISP functions -> A Functions. Elle est aussi bien expliquée dans AIDACAD. L'expression : (and (consp lst) (member T (mapcar fun lst)) ) teste d'abord si lst est une liste non vide (consp lst), si ce n'est pas le cas, cesse l'évaluation et retourne nil, si oui continue l'évaluation et teste si un des éléments de lst retourne T à la fonction fun (member T (mapcar fun lst)), si cette dernière expression retourne nil l'expression complète (and ...) retourne nil, si la première expression ET la deuxième expression contenues dans le (and .. ) retournent T alors (and ... ) retourne T.
-
C'est pas "grillé", nos réponses se complètent ;) Attention quand même, avec WHILE et les fonctions récusives, de s'assurer que la condition fasse qu'à un moment la boucle se termine !
-
Salut, On parle en LISP de fonction "itératives" et de fonctions "récursives" Les premières répètent les mêmes actions soit "tant que la condition est remplie" (while ...), soit un nombre défini de fois (repeat ...) soit pour chaque élément d'une liste (foreach ...) et (mapcar ...). Les fonctions récursives sont des des fonctions qui font appel à elles même dans leur propres définitions, créant un "empilement". C'est moins évident à comprendre, mais tellement élégant (avis personnel). Pour t'aider, tu peux utiliser la fonction TRACE dans la console VisualLISP. Par exemple tu charges la fonction FACT (un classique, voir le lien ci-dessous) et tu lances dans la console (trace fact) puis (fact 6) et tu ouvres la fenêtre suivi et tu verras l'empilement. Tu peux aussi voir dans la Faq AutoLISP ce chapitre et le suivant. Et quelques exemples de routines définies de manière itérative et récursive ici et là. [Edité le 8/6/2006 par (gile)]
