-
Compteur de contenus
1 113 -
Inscription
-
Dernière visite
-
Jours gagnés
42
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par Luna
-
Problème raccourcis commande polyligne
Luna a répondu à un(e) sujet de Hydro8 dans AutoCAD 2020-2024
Coucou, C'est la raison pour laquelle cette mise à jour est quelque peu confuse. Car en définissant les alias utilisateurs, AutoCAD n'est pas capable de faire la traduction en 2 temps : P > POLYLIGN (> POLYLIGNE) Donc il faut obligatoirement avoir 2 fichiers PGP distincts entre les versions 2024+ et 2023 (et antérieures). Si l'on ne fait qu'ajouter des alias utilisateurs, il n'y a aucun problèmes car les alias utilisateurs prévalent sur les alias AutoCAD. Donc définir un alias P > POLYLIGNE ne fera que supprimer la possibilité d'avoir un alias P pour la commande PAN, et la commande POLYLIGNE aura alors 2 alias P ou PO. Bisous, Luna -
Problème raccourcis commande polyligne
Luna a répondu à un(e) sujet de Hydro8 dans AutoCAD 2020-2024
Coucou, AutoCAD 2024 a modifié le nom de certaines commandes françaises (pourquoi ? Aucune idée !). Si tu regardes tout en bas de ton fichier PGP (juste avant les alias utilisateurs), tu devrais avoir ceci : C'est pour cela que @Turtle76 a proposé de rajouter un E (à POLYLIGN et non ton raccourci P) pour ton alias de commande utilisateur. Bisous, Luna -
Un Defun dans un Defun, mais qu'en est-il en fait ?
Luna a répondu à un(e) sujet de DenisHen dans Pour aller plus loin en LISP
Coucou, Vui, le programme s'exécute ligne après ligne (ou plus exactement, fontions/arguments après fonctions/arguments) et si une erreur apparaît, le programme est interrompu. Donc ici comme le (defun) imbriqué est à la fin, on se retrouve avec le cas de figure de (fun_6) qui a besoin que (fun_5) soit exécutée auparavant, sinon (fun_6) n'existe pas encore dans la "timeline" du programme, entraînant alors une erreur. C'est pour cela que tous les (defun) imbriqués sont toujours en début de programme (ou à minima avant l'appel du sous-programme). Mais je suis heureuse de voir que tu es compris cela par toi-même 🙂 Bisous, Luna -
Coucou, Je doute que cela soit possible nativement. Cependant tu peux voir avec de la programmation si cela est possible. Mais le faire à l'ouverture du fichier est en dehors de mes compétences malheureusement. Bisous, Luna
-
Un Defun dans un Defun, mais qu'en est-il en fait ?
Luna a répondu à un(e) sujet de DenisHen dans Pour aller plus loin en LISP
Coucou @DenisHen, Considère les fonctions/commandes comme une maison ou des boîtes avec des portes permettant d'inviter certaines variables ou de retenir prisonnières d'autres variables. Les parenthèses situées à la suite du nom de ta fonction permet de définir tes variables/fonctions localement. Dans le cas ci-dessous, on a pas déclarer de variables locales donc on a une première boîte (nommée fun_1) qui donne naissance à la variable A et celle-ci est libre de sortir de la boîte (fun_1). (defun fun_1 () (setq a 0) ) Ainsi command: (fun_1) 0 command: !a 0 Désormais si je déclare B localement, celle-ci sera créée dans la boîte (fun_2) mais en sera prisonnière (sa valeur retournera à nil une fois l'exécution de (fun_2) terminée). (defun fun_2 (/ b) (setq b 10) ) Donc command: (fun_2) 10 command: !b nil command: !a 0 Ici A est toujours présent car il n'a jamais été remis à nil ou bien modifié. Si désormais je déclare une variable A localement dans une fonction (fun_3), alors celle-ci sera initialisée à nil au lancement de la fonction mais sa valeur est enregistrée et une fois l'exécution de la fonction terminée, elle retrouve sa valeur initiale sans prendre en compte les modifications opérées au cours de la fonction (fun_3). Par exemple (defun fun_3 (/ a) (setq a (1+ a)) ) on aurait command: !a 0 command: (fun_3) ; erreur: type d'argument incorrect: numberp: nil mais si on écrit (fun_3) ainsi (defun fun_3 (/ a) (setq a 1) ) alors command: !a 0 command: (fun_3) 1 command: !a 0 Si dans le cas contraire, je veux avoir une variable capable de se déplacer entre certaines fonctions, alors on ne la déclare pas localement UNIQUEMENT dans les fonctions supposées communiquer entre-elles. (defun fun_4 () (setq a (1+ a)) ) ici on pourra désormais avoir command: !a 0 command: (fun_4) 1 command: (fun_4) 2 command: !a 2 et si je repasse avec (fun_1) command: (fun_1) 0 command: (fun_4) 1 command: !a 1 Bien donc chat c'est la logique avec les variables déclarées ou non localement. Donc si on reprends la métaphore des petites boîtes : - On a 4 boîtes nommées (fun_1), (fun_2), (fun_3) et (fun_4). - La boîte (fun_1) permet de créer une variable A et lui affecte la valeur 0. Cette variable est libre de sortir de cette boîte et de faire sa vie, mais à chaque fois qu'on rentrera dans cette boîte, A aura toujours la valeur 0 à la fin. - La boîte (fun_2) permet de créer une variable B et lui affecte la valeur 10. Cette variable est prisonnière de cette boîte donc à chaque fois qu'on rentre dans cette boîte, B est crée puis disparaît une fois qu'on sort de la boîte (quelque soit le moyen, donc même si une erreur est rencontrée, B disparaît dans tous les cas !). - La boîte (fun_3) permet de créer une variable A, totalement indépendante de la variable A créée par (fun_1) et ayant le même comportement que B avec (fun_2). - La boîte (fun_4) permet d'inviter la variable A et de lui rajouter la valeur 1. On peut donc déduire que si l'on utilise la boîte (fun_4) avant la boîte (fun_1), alors on aura une erreur car A n'existe pas encore, donc impossible de lui rajouter une valeur, puisque (fun_4) dépend directement de l'existence de A. Si désormais on applique cette logique aux fonctions imbriquées : (defun fun_5 () (defun fun_6 () (setq c 5) ) ) alors on a bien command: (fun_5) 5 command: (fun_6) 5 command: !c 5 Et si l'on déclare cette fois-ci (fun_8) localement, alors celle-ci sera créée uniquement lors de l'utilisation de (fun_7) mais celle-ci reprendra sa valeur initiale une fois l'exécution de (fun_8) terminée, c'est-à-dire nil dans le cas présent : (defun fun_7 (/ fun_8) (defun fun_8 () (setq c 7) ) ) donc command: (fun_7) 7 command: (fun_8) ; erreur: no function definition: FUN_8 command: !c 7 Bien et si désormais je déclare localement (fun_6) (defun fun_9 (/ fun_6) (defun fun_6 () (setq c 9) ) ) j'aurais command: !c 7 command: (fun_9) 9 command: !c 9 command: (fun_6) 5 command: !c 5 command: (fun_5) 5 Donc on comprend bien ici que (fun_6) possède un fonctionnement différent selon qu'elle soit appelée depuis (fun_9) par rapport à (fun_5) ou bien (fun_6). Et si l'on considère que (fun_5) n'a jamais été exécutée auparavant alors on aura command: (fun_9) 9 command: (fun_6) ; erreur: no function definition: FUN_6 command: (fun_5) 5 command: (fun_6) 5 command: !c 5 car en effet, (fun_6) n'a aucune existence globale avant l'exécution de (fun_5). Et c'est d'ailleurs là tout l'intérêt de déclarer certaines fonctions localement et d'autres non. Car parfois, on va créer une fonction qui servira dans plusieurs fonctions/commandes (donc on ne les déclare pas localement et elles ont un (defun) isolé) et d'autres fois on va avoir besoin d'une fonction utile uniquement pour une unique fonction ou commande. Et plutôt que de se pourrir notre espace avec des fonctions à usage unique local, on préfère les déclarer localement pour quelle n'existent qu'uniquement en cas de besoin. Cela va arriver très souvent lorsqu'on écrit par exemple une fonction récursive ou même simplement une fonction qui va nous servir localement mais qui n'a pas vraiment de nom défini. Ces fonctions seront bien souvent nommées (foo) voire (f) qui est juste un nom arbitraire et dont on sait qu'aucune autre fonction n'aura besoin d'accéder à cette fonction. C'est d'ailleurs pour cela qu'on se retrouve très souvent avec plusieurs fonctions (foo)/(f) multiples mais totalement différentes dans les déclarations locales de fonctions. Car au même titre qu'il est IMPERATIF de déclarer localement ses variables sauf si une variable DOIT pouvoir être utilisée entre plusieurs fonctions (et dans ce cas précis, on va favoriser un nom différent des autres variables et plutôt équivoque comme par exemple **variable**). Car en effet si on prend l'exemple d'une liste : (defun fun_10 () (setq l (cons 2 l)) ) (defun fun_11 () (setq l (cons (getpoint "\nPoint : ") l)) ) donc ici on a 2 utilisations différentes pour l, mais comme la variable n'est pas déclarée localement, cela devient vite le bordel command: (fun_10) (2) command: (fun_10) (2 2) command: (fun_11) ((10.7014 5.86029 0.0) 2 2) command: (fun_10) (2 (10.7014 5.86029 0.0) 2 2) command: (fun_11) ((43.4978 27.9322 0.0) 2 (10.7014 5.86029 0.0) 2 2) ... Et donc cela peut s'avérer très problématique par exemple si tu cherches à lister les points d'une polyligne mais que tu ne remets pas la liste à nil une fois le programme terminée. Car à la prochaine polyligne, elle aura des points ne lui appartenant pas ! Pour les fonctions déclarée localement c'est pareil. Notamment tu peux trouver une déclaration locale de la fonction (*error*) et il faut ABSOLUMENT la déclarer localement si tu la modifies (il existe une autre méthode prenant la création d'une fonction erreur perso, de lui affecter la valeur de *error* puis de rendre la valeur initiale de *error* une fois terminée, comme on le ferait pour les (getvar)/(setvar), mais perso c'est pas la méthode la plus sûre à mes yeux). Car il ne faut surtout pas perdre sa définition initiale car les fonctions natives d'AutoCAD l'utilisent aussi donc il vaut mieux éviter de la modifier. (defun foo (/ *error*) (defun *error* (msg) (setq a 0) (princ msg) ) (setq a (1+ a)) ) Donc par exemple ici, si A n'est pas un nombre alors A prend la valeur 0 (non déclaré localement) en cas d'erreur puis la fonction (*error*) reprend sa valeur initiale telle que prévue par AutoCAD. Donc command: !a nil command: (foo) ; erreur: type d'argument incorrect: numberp: nil command: !a 0 command: (foo) 1 command: (foo) 2 command: !a 2 Désormais si l'on considère cette vision avec les petite boîte on peut en réalité comprendre qu'on a déjà des boîtes imbriquées via AutoCAD : - une boîte correspondant à Windows (par exemple les variables environnements avec (getenv) et (setenv) ou même les HKEY..) - une boîte correspondant à la session AutoCAD (comme par exemple (vlax-get-acad-object) permettant de connaître le nom des dessins ouverts) - une boîte correspondant au DWG (comme par exemple la base de données DXF de toutes les entités contenues dans le dessin, etc..) - et enfin vient les boîtes avec les différentes fonctions/commandes. Puis les sous-fonctions, etc... C'est pour cela que les variables non déclarées localement ne sont enregistrées que dans le DWG dans lequel elle a été crée, car on ne peut pas remonter l'arborescence avec de simple variables (donc créer une variable A dans Dessin1 et demander la valeur de A dans Dessin2, cela retourne nil). Mais les variables environnement permettent de communiquer entre plusieurs dessins ouverts, et même entre plusieurs sessions d'AutoCAD. Si on reprend par exemple les fichiers acad.lsp et acaddoc.lsp dont le chargement (si inchangé) se fait respectivement au démarrage d'une session AutoCAD et l'autre à chaque ouverture d'un dessin, et bien le fonctionnement est le même. Si on ouvre un 1er Dessin, puis on modifie l'expression d'une fonction et qu'on ouvre ensuite un 2nd Dessin. Suivant que la fonction soit définie sur acad.lsp ou acaddoc.lsp, notre fonction modifiée aura soit, 2 exécutions différentes entre Dessin1 et Dessin2, soit l'ancienne expression que se soit Dessin1 ou Dessin2. Bref...je parle trop ^^" mais considère que la déclaration locale des variables est systématique sauf cas exceptionnels tandis que la déclaration locale des fonctions c'est plutôt l'inverse. Tu auras plutôt envie de ne pas les déclarer sauf cas exceptionnel lorsque tu sais que tu n'utiliseras jamais cette fonction ailleurs ou bien que tu n'as pas d'autres choix (*error*). Ensuite si tu réfléchis avec le principe de boîtes, pour répondre à ta question, si tu déclares localement une variable dans une fonction, et que tu as une sous-fonction, cette sous-fonction étant à l'intérieur de la boîte fonction, la variable (même déclarée localement) pourra être utilisée par la sous-fonction comme si elle été "globale". Et inversement si tu déclares une variable localement dans ta sous-fonction, alors ta fonction principale ne pourra pas connaître sa valeur car elle retournera à sa valeur initiale. (defun fun_12 (/ foo a) (defun foo (b) (* a (1+ b)) ) (setq a 1) (foo a) ) ici on a command: !a nil command: !b nil command: (fun_12) 2 command: !a nil command: !b nil et si tu prends (defun fun_13 (/ foo b) (defun foo (b) (setq b (* a (1+ b))) ) (setq a 1) (setq a (1+ (foo a))) b ) alors command: (fun_13) 2 command: !a 3 command: !b nil car ici, on définie la variable b avec (foo) qui prend alors la valeur 2, mais comme on déclare b localement dans (fun_13), alors b retourne à nil (ou valeur initiale) une fois (fun_13) terminée. Bon assez parlé :3 Bisous, Luna -
Je pense que tu n'utilises pas mon programme ? Car je n'ai pas non plus utilisé la commande AREA ^^" Peut-être change le nom AH de ma commande ? Personnellement je n'ai eu aucun soucis lors de mes tests... Bisous, Luna
-
Alors... Il s'agit d'utiliser mon programme SANS MODIFICATIONS car je n'ai pas écrit "_OSMODE" mais "OSMODE"... ^^" Bisous, Luna
-
Coucou, As-tu testé la routine RBloc de Patrick_35 ? De souvenir elle fonctionne sans soucis (aucune idée si cela correspond parfaitement à ton besoin cependant). J'ai également souvenir que depuis la version 2021 (?), je ne suis plus certaine de la version exacte..., AutoCAD a intégré nativement la possibilité de redéfinir une définition de bloc si l'on tente d'insérer un bloc issu d'un autre dessin sous condition que les deux blocs portent strictement le même nom et une définition de bloc différente. Cependant, aucune idée d'à quel point c'est conservateur concernant les propriétés dynamiques et attributs. Bisous, Luna
-
Ah bah, @lecrabe et sa bibliothèque de 3001 (?) routines sont toujours plus rapides 🙂 Bisous, Luna
-
Coucou, Quelque chose comme cela peut-être ? (defun c:AH (/ acc mode pt obj txt) (setq acc (getvar "OSMODE")) (setvar "OSMODE" 0) (initget "Supprimer Conserver") (setq mode (cond ((getkword "\nSupprimer ou conserver le contour ? [Supprimer/Conserver] <Conserver> : ")) ("Conserver"))) (command "_-BOUNDARY" (setq pt (getpoint "\nSpécifiez un point interne : ")) "") (setq obj (vlax-ename->vla-object (entlast))) (cond ( (= "Supprimer" mode) (setq txt (rtos (vla-get-area obj))) (entdel (entlast)) ) ( (= "Conserver" mode) (setq txt (strcat "%<\\AcObjProp Object(%<\\_ObjId " (itoa (vla-get-ObjectID obj)) ">%).Area \\f \"%lu2\">%")) ) ) (command "_-HATCH" "_Properties" "ANSI31" "" "" pt "") (command "_-TEXT" "_Justify" "_MC" pt "" "" txt) (setvar "OSMODE" acc) (princ) ) Pour info, la première question "Supprimer/Conserver" permet de définir si tu souhaites supprimer le contour généré. S'il est supprimé alors le texte inséré sera un simple texte. Si le contour est conservé alors le texte sera sous forme de champs dynamique pointant sur la propriété "Aire" du contour, permettant ainsi de mettre à jour le texte si le contour est modifié. Bisous, Luna
-
En regardant ton programme, même de base il est non fonctionnel... Je vais regarder pour écrire quelque chose de plus solide parce qu'en l'état, ce programme ne sert à rien (peut-être suis-je médisante mais cela ressemble fortement à du ChatGPT qui baragouine du LISP sans comprendre ce qu'il fait..) Bisous, Luna
-
Coucou, Je pense que le fichier à été développé en anglais mais il n'a pas été écris à l'internationale. Pour cela il suffit de rajouter un underscore ("_") devant chaque nom de commande dans ton fichier s'il n'y en a pas (idem pour les options de commandes). Par exemple remplacer "-BOUNDARY" par "_-BOUNDARY" Bisous, Luna
-
Coucou @OlivierR, Si je comprends bien ton programme, il permet de faire un "Enregistrer sous" de ton dessin courant, c'est bien cela ? Si c'est le cas, première question : pourquoi ne pas utiliser "Enregistrer sous" directement plutôt que de passer par un programme ? Si toutefois il faut passer par le programme, techniquement parlant tu crées un nouveau fichier à l'emplacement choisi, donc la fonction (getfiled) avec les bits 4 (nom/extension arbitraire) et 1 (créer un nouveau fichier) devrait te permettre de faire ce que tu désires. En effet il te suffit ensuite de supprimer le nom de fichier du retour de (getfiled), ce qui te donnera le nom du dossier, puis d'y greffer le nom de ton fichier en cours (ou tout autre nom si tu le souhaites) afin de créer le nouveau fichier à l'emplacement spécifié. Par exemple (setq str (getfiled "" "" "" 5)) (setq pos (vl-string-position 92 str 0 T)) (setq dos (substr str 1 pos)) ;; Retourne le nom du dossier (sans les \\ séparateur pour le nom du fichier), remplacer 'pos' par '(1+ pos)' pour ajouter le \\ (setq dwg (getvar "DWGNAME")) (setq fil (strcat dos "\\" dwg)) Pour info le 92 correspond au code ascii pour le caractère \ (permettant de séparer les dossiers). La variable 'dos' aura pour valeur quelque chose comme cela : "C:\\Users\\username\\AutoLISP" La variable 'dwg' : "Dessin1.dwg" Et donc 'fil' : "C:\\Users\\username\\AutoLISP\\Dessin1.dwg" Bisous, Luna
-
Le DCL est formidable, mais très ironique, en fait...
Luna a répondu à un(e) sujet de DenisHen dans LISP et Visual LISP
Coucou @DenisHen, En effet le site AfraLisp est plutôt bien fourni là-dessus. Tu peux également regarder du côté de https://autolisp-exchange.com/Tutorials/MyDialogs.htm L'ergonomie du site fait certes un peu mal aux yeux mais les explications sont vraiment intéressantes et surtout il couvre de nombreux cas de figures ! Mais je reconnais que la création d'une DCL digne de ce nom est vraiment pas simple et on doit parfois y aller à tâtons (notamment pour aligner, centrer, espacer, ... correctement chaque élément pour un rendu correct) ce qui prends beaucoup trop de temps pour rien mais bon... Je pense sincèrement que le problème majeur du langage DCL est tout bonnement l'absence totale d'aperçu "dynamique" lorsqu'on crée une boîte DCL et notamment le fait qu'il faut être bien rodé en DCL déjà pour comprendre qu'à chaque test de DCL, il faut toujours prévoir dès le début une gestion des erreurs, autrement on est coincé dans notre DCL qui ne fonctionne pas et on n'a pas d'autre choix que de faire une "fin de tâche" à AutoCAD... Mais d'un autre côté cela permet aussi parfois d'éviter de faire des DCL un peu trop usine à gaz et donc de rester vraiment simple et concis (à la fois pour le développeur que pour l'utilisateur). Et au final on arrive malgré tout par y arriver mais oui, il faut prendre le temps, c'est sûr.. Bisous, Luna -
Attention tout de même car @oze a précisé être sur AutoCAD LT (donc peut-être pas le bon forum mais bon) mais les versions LT supporte la programmation LISP uniquement depuis la version 2024 (et notamment sans certaines fonctions donc cela pourrait ne pas fonctionner de toute façons selon les choix du programmeur) ! Donc cette méthode ne fonctionne pas forcément. Mais en effet si la programmation est supportée, parfois on peut se simplifier la vie via des programmes développés par la communauté. Je pense tout de même que maîtriser les bases d'AutoCAD est primordial avant même de s'aider de programmation custom. Et nan malheureusement.. Mais j'aime bien m'embêter et chaque question est différente en soit donc c'est mieux de prendre le temps ^^" Bon courage pour la suite :3 Bisous, Luna
-
Coucou, Il n'y a pas qu'une seule solution à un problème et les méthodes pour déplacer, décaler, etc... depuis un point référence à partir d'un point spécifique, il existe plusieurs possibilités et certaines possibilités seront plus adéquates dans certaines situations que dans d'autres. Dans un premier temps je dirais qu'il faut déjà que tu "apprivoises" les accrochages objets (voir capture ci-dessous, en cliquant sur la petite flèche vers le bas à droite de l'icône puis choisir "Paramètres d'accrochage aux objets" dans la liste déroulante) afin de voir lesquels tu as besoin au quotidien. Je dirais que les plus importants sont "Extrémité", "Milieu", "Centre", "Intersection" et "Extension" (mais chat reste un avis personnel). Ces accrochages objets sont activables/désactivables via la touche F3 du clavier et s'ils sont activés alors à chaque fois que tu approches ton curseur d'un objets possédant une accroche cochée, AutoCAD te proposera de s'agripper à cette accroche par défaut. Ensuite si jamais tu as besoin d'une accroche spécifique temporairement, tu peux soit connaître les raccourcis clavier par cœur ("_end", "_mid", "_cen", "_int", ...) mais si tu débutes ce n'est pas conseillé ou bien par exemple utiliser Shift+right clic qui permet d'afficher une liste déroulante (voir ci-dessous) avec quelques accroches objets supplémentaires (comme "Milieu entre 2 points", très utile de mon point de vue). Il existe évidemment d'autres possibilités pour gérer tes accrochages objets, notamment par le ruban mais n'étant pas une utilisatrice ruban, je ne saurais pas trop te conseiller sur son utilisation. Une fois les accrochages objets maîtrisés, il existe également les coordonnées. AutoCAD est capable de gérer 3 renseignement de coordonnées différentes : • coordonnées absolues: ces coordonnées correspondent aux coordonnées X Y (Z) de ton point à créer par rapport à ton référentiel de coordonnés (SCG/SCU). Elles s'écrivent comme ceci "X,Y(,Z)" où X, Y et Z sont des nombres appartenant à l'ensemble R (donc tout nombre réel négatif ou positif). Le point de référence est donc l'origine de ton SCG/SCU donc par exemple écrire 0,0 signifie que tu veux placer ton point à l'origine de ton plan. Et écrire -55.23,45 signifie que ton point aura pour coordonnées X -55.23 et en Y 45. • coordonnées relatives: ces coordonnées correspondent à la distance en X Y (Z) de ton point à créer par rapport au dernier point renseigné. Elles s'écrivent comme ceci "@ΔX,ΔY(,ΔZ)" où ΔX, ΔY et ΔZ représente les coordonnées vectorielles X, Y et Z entre ton premier point et du point que tu souhaites créer. Donc ces nombres appartiennent également à l'ensemble R et à l'instar des coordonnées absolues dont l'origine du SCG/SCU sert de référence, cette fois-ci tu utilises un point existant comme référence. Dis-toi simplement que c'est comme si tu créés un plan temporaire dont son origine 0,0,0 correspond aux dernières coordonnées renseignées. Donc par exemple si tu écris @-55.23,45 cela signifie que tu veux créer un point avec un ΔX de -55.23 (donc une distance de 55.23 unités et vers la gauche si dans SCG) et un ΔY de 45 (donc une distance de 45 unités et vers le haut si dans SCG). • coordonnées polaires: ces coordonnées correspondent à la norme de ton vecteur et à son angle (bien qu'ici tu peux entrer une distance aussi bien positive que négative pour la norme). En résumé cela signifie que tu donnes la longueur et l'angle permet de donner le sens et la direction du vecteur. Elles s'écrivent comme ceci "@D<A" où D est la longueur (appartenant à R) et A l'angle (dans les unités définies dans ton dessin donc degrés, radians, grades, etc..) de ton vecteur de déplacement. Comme pour les coordonnées relatives, le "@" signifie que tu utilises le dernier point renseigné comme origine de ton référentiel. Donc par exemple si tu souhaites créer un point dans un rayon de 10m avec un angle de 60° tu peux écrire @10<60. PS: Bien noté que la virgule est le séparateur pour les coordonnées et le point le séparateur décimal. Dans ton cas, qu'appelles-tu l'axe du rectangle ? Est-ce le milieu géométrique de ton rectangle donc le point situé au centre de ton rectangle, ou bien s'agit-il de l'axe X ? L'axe Y ? De quel point s'agit-il précisément ? Je viens de voir ton message, donc si cela correspond au centre géométrique de ton rectangle, tu peux par exemple faire 1. sélectionner ton rectangle 2. commande DEPLACER 3. shift + clic droit > "Centre géométrique" (et cliquer sur ton objet rectangle, si c'est une polyligne fermée) ou bien "Milieu entre 2 points" (et cliquer sur deux sommets formant la diagonale par exemple afin d'obtenir ton point de déplacement sur le centre géométrique) 4. shift + clic droit > "Depuis" (signifie que tu vas spécifier toi-même un point de référence) 5. cliquer sur l'intersection entre ta ligne verticale et horizontale (car tu veux faire tes déplacements par rapport à ces 2 lignes) et cela va donc servir de référence pour définir ton point d'arrivée pour la commande DEPLACER) 6. renseigner les déplacements en coordonnées relatives : @50,100 (si tes unités sont en cm, mais si elles sont en m alors il faudrait écrire @0.5,1) Ton rectangle sera placé comme souhaité (ou alors j'ai rien compris et j'en suis navrée...) 🙂 Bisous, Luna
-
Lisp extraction de données a l'intérieur d'une polyligne fermée (bloc, att, texte et multitexte)
Luna a répondu à un(e) sujet de Bhoo dans AutoCAD 2020-2024
Coucou, Je remarque ici que tu as opté pour l'option de sélectionner l'ensemble des objets (en l’occurrence ici les "INSERT") du dessin pour ensuite vérifier si leur point d'insertion est situé dans ta polyligne. Je pense que tu gagneras fortement en efficacité en complexifiant un peu ta fonction de sélection (ssget). En effet, cette fonction possède de très nombreuse possibilités et notamment les mots clés. Tu as écrit (si tu n'oublies pas l'underscore évidemment) : (ssget "_X" '((0 . "INSERT"))) ce qui se traduit par "sélectionner tout les objets 'INSERT' de la base de donnée du dessin". Or dans ton cas, il serait plus judicieux d'utiliser (ssget "_CP" pt_list '((0 . "INSERT"))) ;; "_CP" = Crossing Polygon (capture polygonale donc un polygone de sélection vert) ;;ou bien (ssget "_WP" pt_list '((0 . "INSERT"))) ;; "_CP" = Window Polygon (fenêtre polygonale donc un polygone de sélection bleu) où 'pt_list' correspond à une liste de coordonnées de points 2D comme ceci par exemple ((23.45 93.01) (-1.00 4.79) (11.15 -13.405)) Autrement dit, fais bien attention au contenu de ta variable 'vertices' et plus exactement à son format ! Car certes c'est une méthode qui semble simple pour récupérer les coordonnées mais en réalité, cela requiert un peu de traitement selon les autres fonctions utilisant ces coordonnées... Normalement tu auras un format comme ceci : (23.45 93.01 -1.00 4.79 11.15 -13.405) Ce qui, comme tu peux le voir, ne correspond pas vraiment à une liste de coordonnées de points 2D. Il existe de nombreuses manières pour récupérer la liste des coordonnées d'une polyligne donc je suis sûre que tu trouveras une solution (car après tout tu sembles être surtout là pour apprendre et non pour recopier). Ainsi, en passant par ces options de sélection ("_CP" ou bien "_WP" selon ton besoin réel) tu peux directement filtrer ta sélection d'objets sur une zone précise de ton dessin, permettant ainsi de ne pas avoir besoin d'étudier les potentiels 10 000 références de blocs contenues dans ton dessin mais de juste se concentrer sur la zone de travail souhaitée (ce qui est beaucoup plus rapide à l'exécution !). Du coup ta fonction (is-point-inside-polyline) n'est plus nécessaire. Ensuite pour la récupération des attributs d'un bloc, je te conseille les fonctions de LeeMac qui sont vraiment simple d'utilisation et assez simple à comprendre (donc pas besoin de réécrire une fonction par toi-même, des fois on peut se servir de ce qui existe déjà et qui fonctionne très bien ;p) : http://www.lee-mac.com/attributefunctions.html Ensuite un conseil, si tu débutes en LISP, peut-être qu'avant d'insérer tes résultats dans un tableau AutoCAD (qui sont des entités complexes à maîtriser) tu devrais essayer de trouver une méthode plus simple pour toi en temps que programmeur. Tu peux facilement créer un fichier .csv par exemple (utilisable par Excel). Ou bien trouver d'autres alternatives. Si tu as besoin de plus de précisions, ou bien d'exemples de programmation plus concrets n'hésites pas à demander ! C'est pour chat qu'on est là, et chat fait toujours plaisir d'aider quelqu'un qui désire apprendre 😜 Bisous, Luna -
Modifier simultanément des TextMult sur l'ensemble d'un projet
Luna a répondu à un(e) sujet de Lucas DE AMORIM dans Routines LISP
Coucou, J'allais répondre mais apparemment @(gile) a été plus rapide.. Donc juste une petite remarque sans importance : personnellement je préfère insérer les messages d'exécution réussie dans la condition VRAI de la fonction conditionnelle associée. Ainsi le message s'affiche uniquement si modification il y a eut. Et voir même dénombrer le nombre de mises à jour effectuées par rapport au nombre d'objets sélectionnés ou bien créer un jeu de sélection avec uniquement les objets modifiés afin de le rendre actif à la fin de la commande. Bref, c'est juste du détails sans importance et c'est juste du confort d'utilisation on va dire 🙂 Bisous, Luna -
pas de soucis, bien que je n'ai rien fait pour le coup ^^ Bisous, Luna
-
Coucou, Je ne connais pas ZWCAD mais j'ai envie de supposer que la fonction (acet-ui-single-select) pose un soucis. Je ne connais pas cette fonction mais d'après son nom je suppose qu'il s'agit d'une manière détournée de faire un (ssget "_+.:E:S") permettant ainsi d'appliquer un filtre sur une sélection similaire à un (entsel) ou (nentsel). Essaye peut-être avec ceci ? (Defun C:tz (/ *error*);Define new command line function ;DEBUT TRAPPE ERREUR (SORTIE ESCAPE) (defun *error* (msg) (if (not (member msg '("console break" "Function cancelled" "quit / exit abord"))) (princ (strcat "\nError: " msg)) ) (setvar "osmode" oldosmode) (princ) ) ;FIN TRAPPE ERREUR (setq oldosmode (getvar "osmode")) (setq E null) (while (= E null) (command "-accrobj" "pro") (princ "\nSélectionnez un objet TEXTE") (setq na (ssget "_+.:E:S" '((-4 . "<OR") (0 . "TEXT") (-4 . "<AND") (0 . "POLYLINE") (-4 . "<NOT") (-4 . "&") (70 . 112) (-4 . "NOT>") (-4 . "AND>") (-4 . "OR>")) );ssget );setq (if na (progn (Command "changer" na "" pause "" "" pause "") (command "-accrobj" "") (command "deplacer" "p" "" "@" pause) (Command "changer" na "" "p" "co" "ducalque" "") );progn );if (if (not na) (progn (setq E "fin") ;(command "-accrobj" "nod,int,ext") (setvar "osmode" oldosmode) );progn );if (princ) );while );Defun (Defun C:tzx (/ *error*);Define new command line function ;DEBUT TRAPPE ERREUR (SORTIE ESCAPE) (defun *error* (msg) (if (not (member msg '("console break" "Function cancelled" "quit / exit abord"))) (princ (strcat "\nError: " msg)) ) (setvar "osmode" oldosmode) (princ) ) ;FIN TRAPPE ERREUR (setq oldosmode (getvar "osmode")) (setq E null) (while (= E null) (command "-accrobj" "pro") (princ "\nSélectionnez un objet TEXTE") (setq na (ssget "_+.:E:S" '((-4 . "<OR") (0 . "TEXT") (-4 . "<AND") (0 . "POLYLINE") (-4 . "<NOT") (-4 . "&") (70 . 112) (-4 . "NOT>") (-4 . "AND>") (-4 . "OR>")) );ssget );setq (if na (progn (command "copier" na "" "@" "@") (Command "changer" na "" pause "" "" pause "") (command "-accrobj" "") (command "deplacer" "p" "" "@" pause) );progn );if (if (not na) (progn (setq E "fin") ;(command "-accrobj" "nod,int,ext") (setvar "osmode" oldosmode) );progn );if (princ) );while );Defun Je n'ai pas testé. Je me pose également la question à quoi sert le filtre de sélection justement car tu parles uniquement de texte donc pourquoi le filtre autorise-t-il une polyligne également ? Car de ce que j'entends, on pourrait fortement simplifier le filtre au vue de ton utilisation... Il serait également judicieux de mettre le nom des commandes et choix d'options en anglais. Bisous Luna
-
[résolu] editsolide sur tous les objets 3D d'un fichier
Luna a répondu à un(e) sujet de cath287 dans Débuter en LISP
pas de soucis ! Bisous, Luna -
[résolu] editsolide sur tous les objets 3D d'un fichier
Luna a répondu à un(e) sujet de cath287 dans Débuter en LISP
Coucou, Dans un premier temps, as-tu testé ton programme pas à pas pour savoir à quelle ligne précisément tu avais une erreur ? Ensuite, je pense que le problème vient de car cette notation indique l'exécution d'une fonction sans arguments (comme (ssget) par exemple).. Or ici elst n'est pas une fonction mais une liste correspondant au (entget) de l'entité n. Donc la notation correcte serait (defun c:repfich (/ jeusel n ent elst) (command "controle" "Oui") (command "purger" "tout" "" "non") (command "purger" "appsenreg" "" "non") (command "repcontour" (setq jeusel (ssget "_X" '((0 . "3Dsolid")))) "" ) (setq n 0) (if jeusel (while (setq ent (ssname jeusel n)) (setq elst (entget ent)) (setq n (1+ n)) (command "editsolide" "corps" "nettoyer" elst "quitter" "quitter" ) ) ;fin de while ) ;fin de if ) Je me suis permise de corriger 2-3 petite choses notamment l'ajout des variables locales (sur la ligne du (defun) après le / ) et la suppression du doublon du (ssget) étant donné que tu affectes déjà ce jeu de sélection à la variable jeusel, autant l'utiliser 🙂 Je ne peux que te conseiller également de mettre le nom des commandes et options en international pour éviter tout soucis de traduction des commandes mais également de passer par les commandes avec tirets ("_-PURGE" par exemple) qui sont les commandes sans ouverture de boîte de dialogues (donc tout se fait via ligne de commande, beaucoup plus adapté à de la programmation). Bisous, Luna -
AutoCAD 2021 : Recherche de texte pour un attribut (Equivalent RECHERCHEV Excel)
Luna a répondu à un(e) sujet de ST4423 dans AutoCAD 2020-2024
Coucou @ST4423, S'il s'agit d'une simple table d'équivalence (du genre pour un unique repère on a un unique libellé), alors on pourrait imaginer d'utiliser une table des propriétés de bloc (voir l'aide >>ici<<). Cela te permet de sélectionner un repère via une liste déroulante et cela mettra à jour directement ton libellé associé. L'avantage c'est que tu peux préparer ta table d'équivalence dans Excel et faire un simple copier/coller dans la table d'AutoCAD puisqu'il s'agit d'un tableur. Le seul inconvénient que je vois serait que cette action dynamique de lier une valeur d'attribut à une valeur d'un autre attribut ne peut fonctionner qu'en passant par la flèche déroulante de la référence de bloc. Autrement dit, il ne me semble pas que cela soit possible d'écrire la valeur à la main dans la palette des propriétés du bloc et que cela mette à jour le libellé automatiquement. Bisous, Luna -
Coucou @philsogood, J'ai souvenir de ce sujet qui avait justement un problème pour renommer des blocs anonymes, empêchant toutes manipulations. Peut-être que les solutions proposés par PHILPHIL et/ou Steven pourront t'aider pour renommer ces blocs anonymes et ensuite les décomposer. Bisous, Luna
-
Coucou, As-tu testé la routine RBLOC de notre regretté Patrick_35 ? De souvenirs elle fonctionne aussi bien avec les blocs dynamiques. Bisous, Luna
