-
Compteur de contenus
12 247 -
Inscription
-
Dernière visite
-
Jours gagnés
208
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par (gile)
-
[ RÉSOLU] Sens de parcours des polylignes (Horaire ou anti-horaire)
(gile) a répondu à un(e) sujet de TUAU dans AutoCAD 2020-2024
Salut, On devrait pouvoir s'inspirer de ce sujet. -
Oui, mais pas seulement, beaucoup de groupes DXF sont optionnels. Le Manuel d'utilisation DXF est assez complet et en français (donc pas d'excuses).
-
On ferait ça : (setq elst (entget ligne)) (entmod (subst '(62 . 7) (assoc 62 elst) elst)) Sauf que, avec le groupe DXF 62, il faut faire attention,parce qu'il peut être absent de la liste renvoyée par entget si l'entité est en couleur DuCalque. Donc en fait, on ferait plutôt : (setq elst (entget ligne)) (if (setq couleur (assoc 62 elst)) (entmod (subst '(62 . 7) couleur elst)) (append elst (list '(62 . 7))) )
-
Je change la couleur rouge en blanc des lignes trop courtes.
-
On peut améliorer la sélection des objets "non traités" en utilisant les xdata plutôt que les ldata parce qu'on peut les utiliser pour filtrer une sélection (voir ce sujet). Dans ce cas, la fonction 'dejaRaccourcie' n'est plus utile. (defun marquerRaccourcie (ligne) (if (null (tblobjname "APPID" "DecoupPli")) (regapp "DecoupPli") ) (entmod (append (entget ligne) '((-3 ("DecoupPli" (1070 . 1)))))) ) (defun c:test (/ s i l) (if (setq s (ssget '((0 . "LINE") (62 . 1) (-4 . "<NOT") (-3 ("DecoupPli")) (-4 . "NOT>") ) ) ) (repeat (setq i (sslength s)) (setq l (ssname s (setq i (1- i)))) (raccourcirLigne l 3.) (marquerRaccourcie l) ) ) (princ) )
-
Un peu de méthodologie. Quand on effectue une tâche "complexe", il est d'usage de la décomposer en plusieurs tâches plus simples testables séparément. Ici, la "complexité" de la tâche est de modifier la longueur de plusieurs lignes à condition que ce là n'ait pas été déjà fait. On peut donc décomposer en plusieurs tâches : sélectionner des lignes tester si une ligne a déjà été raccourcie raccourcir une ligne marquer la ligne comme "déjà raccourcie" Les tâches 2, 3 et 4 peuvent être définies dans des fonctions séparées testables indépendamment. Pour que la tâche 4 fonctionne correctement après la tâche 3, il faut que la ligne passée en argument à la tâche 3 soit juste modifiée, pas remplacée par une autre entité. 2. (defun dejaRaccourcie (ligne) (= (vlax-ldata-get ligne "DecoupPli") 1) ) 3. (defun raccourcirLigne (ligne longCoupe / ptA ptB long ang) (setq ptA (getpropertyvalue ligne "StartPoint") ptB (getpropertyvalue ligne "EndPoint") ang (angle ptA ptB) ) (if (<= (distance ptA ptB) (* 2 longCoupe)) (entmod (subst '(62 . 7) '(62 . 1) (entget ligne))) (progn (setq ptC (polar ptA ang longCoupe) ptD (polar ptB ang (- longCoupe)) ) (setpropertyvalue ligne "StartPoint" ptC) (setpropertyvalue ligne "EndPoint" ptD) (entmake (list '(0 . "LINE") (cons 10 ptA) (cons 11 ptC) '(62 . 7)) ) (entmake (list '(0 . "LINE") (cons 10 ptB) (cons 11 ptD) '(62 . 7)) ) ) ) ) 4. (defun marquerRaccourcie (ligne) (vlax-ldata-put ligne "DecoupPli" 1) ) Chacune de ces fonctions peut être testée séparément dans AutoCAD avec les expressions suivantes : (dejaRaccourcie (car (entsel))) (raccourcirLigne (car (entsel)) 3.) (marquerRaccourcie (car (entsel))) Une fois qu'on est satisfait du fonctionnement de ces fonctions, on peut les intégrer dans le traitement d'un jeu de sélection. (defun c:test (/ s i l) (if (setq s (ssget '((0 . "LINE") (62 . 1)))) (repeat (setq i (sslength s)) (setq l (ssname s (setq i (1- i)))) (if (not (dejaRaccourcie l)) (progn (raccourcirLigne l 3.) (marquerRaccourcie l) ) ) ) ) (princ) )
-
Salut, Quand tu fais: (/= (vlax-ldata-put ssObj "DecoupPli" 1) "1") Que penses-tu tester ? Que renvoie (vlax-ldata-put ssObj "DecouPli" 1) ? Sinon, dans la liste d'un filtre de sélection, le "AND" est implicite, il est donc inutile quand il enveloppe toute la liste. Et le "OR" est tout autant inutile quand il n'enveloppe qu'une seule condition. (defun c:test (/ ss i line p1 p2 d v) (if (setq ss (ssget '((0 . "LINE") (62 . 1)))) (repeat (setq i (sslength ss)) (setq line (ssname ss (setq i (1- i))) p1 (getpropertyvalue line "StartPoint") p2 (getpropertyvalue line "EndPoint") ) (if (/= (vlax-ldata-get line "DecoupPli") 1) (if (<= (setq d (distance p1 p2)) 6.) (entdel line) (progn (setq v (mapcar '(lambda (x1 x2) (* (/ (- x2 x1) d) 3.)) p1 p2)) (setpropertyvalue line "StartPoint" (mapcar '+ p1 v)) (setpropertyvalue line "EndPoint" (mapcar '- p2 v)) (vlax-ldata-put line "DecoupPli" 1) ) ) ) ) ) (princ) ) Mais le plus simple pour "savoir si c'est déjà fait" serait de changer de couleur.
-
[<= 2013] Rendre les calques verrouillés non sélectionnables (3, le retour)
(gile) a répondu à un(e) sujet de (gile) dans ObjectARX/DBX, C++, .NET, RealDWG
Salut, Tu devrais trouver un dossier "LayLockSel.bundle" dans le répertoire : "C:\ProgramData\Autodesk\ApplicationPlugins". Il suffit de supprimer ce dossier pour désinstaller le programme. -
Toujours pas sûr de comprendre (tu relis tes messages avant de les poster ?). Je ne sais pas ce que tu appelles "dans la mémoire". Ceci dit, il semble que l'attribut en question soit un champ et que le "_m²" qui te pose soucis soit simplement un suffixe paramétré dans de format du champ. Il serait tellement plus simple que tu attaches un fichier avec ce bloc...
-
Compiler programme LISP
(gile) a répondu à un(e) sujet de PATRICE69 dans Pour aller plus loin en LISP
Salut, Pour compiler un fichier .lsp en ficher .fas, on peut utiliser la fonction LISP vlisp-compile (Windows uniquement). -
Ça me rassure, je ne suis pas le seul. J'ai donné lien vers 'SelectiveAttSync' parce que @didier en parlait, mais je suis bien incapable de dire si ça peut répondre à la demande (s'il y en a une).
-
Personnellement, je n'ai pas réussi à plus de quelques lignes du message initial. Si, comme suggéré dans les réponses (lisibles elles), il s'agit bien de synchronisation d'attributs, le sujet concernant la synchronisation sélective des attributs est ici.
-
Comment raccourcir une ligne d'une de ses extrémités.
(gile) a répondu à un(e) sujet de DenisHen dans Débuter en LISP
Salut, MODIFLONG (_LENGTHEN). -
@PATRICE69 Pour un fichier .INI "correctement formaté" (les fichiers .INI ne sont pas aussi stricts que les fichiers XML ou JSON), tu peux utiliser les fonctions LISP des ExpressTools acet-ini-get et acet-ini-set.
-
Non, reverse, c'est pour inverser la liste. Plutôt que d'essayer de deviner, consulte l'aide.
-
Salut, Tu peux utiliser le LISP Soustrac disponible sur cette page.
-
(... suite) Les fonctions lambda sont largement utilisées avec les fonctions dite "d'ordre supérieur". Les fonctions d'ordre supérieur sont des fonctions qui prennent en argument une (ou des) fonction(s) et/ou qui renvoient une fonction. Avec AutoLISP plusieurs fonctions natives sont d'ordre supérieur : apply, mapcar, vl-sort, vl-remove-if, etc. Dans le cas présent, la fonction lambda : lambda (x) (= (car x) 42)), utilisée avec vl-remove-if-not, pourrait être remplacée par une fonction "nommée". (defun EstUnGroupe42 (x) (= (car x) 42)) (reverse (vl-remove-if-not 'EstUnGroupe42 entlist))
-
C'est assez général chez tous le débutants, parce qu'on a tous débuté en prenant les choses à l'envers : du particulier vers le général (le fondamental, les bases). Quand on commence avec AutoLISP, on veut commander AutoCAD, donc les premiers codes qu'on écrit commencent par (defun c:... ). Autrement dit par une définition de fonction d'un type (très) particulier. Particulier parce qu'on peut appeler cette fonction comme une commande AutoCAD, donc hors contexte AutoLISP, mais surtout parce qu'il s'agit d'une fonction qui ne prend aucun argument et dont on ne soucie pas de la valeur de retour (généralement même, on masque cette valeur avec un (princ)). Les premières interrogations viennent souvent les premières fois qu'on rencontre des définitions de fonction dont le nom n'est pas c:... et qui prennent des arguments, des fonctions classiques, quoi !... Qui, comme en mathématiques, servent à renvoyer une valeur en fonctions des arguments/paramètres qui leur sont passés. On se rend compte alors qu'il est possible de définir ses propres fonctions (pour étendre le langage ou mieux organiser son code) et les appeler comme on le fait avec les fonctions natives. Là on commence à s'approcher des bases (par lesquelles il eut fallut commencer) : les définitions de fonction et les applications de fonction. Définition d'une fonction nommée sqr qui prend en argument un nombre et renvoie le carré de ce nombre: (defun sqr (x) (* x x)) Application de la fonction précédemment définie au nombre 4: (sqr 4) Une définition de fonction "nommée" a toujours la même structure : (defun symbol ([arg1 ...] [/ var1 ...]) body) où symbol est le nom de la fonction (sqr dans l'exemple), ([arg1 ...] [/ var1 ...]) la liste des éventuels arguments et variables locales ((x) dans l'exemple) et body est le corps de la fonction ((* x x) dans l'exemple). Mais une fonction LISP n'est pas nécessairement "nommée", elle peut être "anonyme", c'est ce qu'on appelle une fonction lambda. Une fonction lambda a exactement la même structure qu'une fonction "nommée" sans le "nom" (symbol) et en appelant lambda à la place de defun : (lambda ([arg1 ...] [/ var1 ...]) body) (lambda (x) (* x x)) Une fonction lambda est une définition de fonction, pas une application de fonction. Comme elle est "anonyme", pour l'utiliser dans une application de fonction, on utilise directement la définition de fonction, par exemple, on remplace sqr dans (sqr 4) par (lambda (x) (* x x)). ((lambda (x) (* x x)) 4) En résumé, la fonction defun sert à lier une définition de fonction à un symbole (comme setq sert à lier le résultat de l'évaluation d'une expression à un symbole), mais on peut, avec lambda, utiliser directement une définition de fonction sans la lier à un symbole (comme on peut utiliser directement le résultat de l'évaluation d'une expression sans le lier à un symbole). En pratique, quand une définition de fonction doit servir plusieurs fois, on préfère l'affecter à une symbole en utilisant defun mais si la définition ne sert qu'une seule fois, une fonction lambda permet d'avoir la définition à l'endroit même du code où elle est appelée.
-
Un Defun dans un Defun, mais qu'en est-il en fait ?
(gile) a répondu à un(e) sujet de DenisHen dans Pour aller plus loin en LISP
Salut, Je ne suis pas certain de comprendre ce que tu cherches à faire mais le symbole 'MacroA' est nil parce qu'il n'y a ni (setq MacroA ..) ni (defun MacroA ...) dans ton code. Le nom de la fonction est : 'c:MacroA' et si tu veux lancer la fonction dans la console il faut le mettre entre parenthèses : (c:MacroA) -
La séquence suivante devrait suffire pour redéfinir un bloc sans insérer de bloc. (command "_.insert" (strcat nomBloc "=" cheminFichierBloc))(command) Tout ce que tu ferais en VBA AutoCAD tu peux le faire en Visual LISP. Les deux utilisent la même API COM/ActiveX.
-
Dans le premier message de ce sujet : ;; gc:GetExtDict (gile) ;; Retourne le dictionnaire d'extension de l'entité (ou nil) ;; ;; Argument : ent (ENAME) (defun gc:GetExtDict (ent) (cdadr (member '(102 . "{ACAD_XDICTIONARY") (entget ent))) ) et ;; gc:GetDictEntries ;; Retourne la liste des entrées du dictionnaire ;; sous forme de paires pointées (key . ename) ;; ;; Argument : dict le dictionnaire (ENAME ou liste DXF) (defun gc:GetDictEntries (dict / result) (and (= (type dict) 'ENAME) (setq dict (entget dict))) (while (setq dict (vl-member-if (function (lambda (x) (= (car x) 3))) (cdr dict))) (setq result (cons (cons (cdar dict) (cdadr dict)) result)) ) (reverse result) ) Ensuite, il suffit de faire: (and ;; ename de la table des calques (setq layerTable (cdr (assoc 330 (entget (tblobjname "layer" "0"))))) ;; ename du dictionnaire d'extension (setq xdict (gc:GetExtDict layerTable)) ;; données DXF du dictionnaire "ACAD_LAYERFILTERS" (setq filterDict (dictsearch xdict "ACAD_LAYERFILTERS")) ;; liste des entrées (setq filters (gc:GetDictEntries filterDict)) )
-
Proposition d'un pense-bête pour les accès au registre Windows.
(gile) a répondu à un(e) sujet de DenisHen dans Pour aller plus loin en LISP
Tu n'as pas lu attentivement, les variables système permettent un contrôle des valeurs bien plus précis. Avec getenv / setenv : la valeur est uniquement de type chaînes de caractère sans espace la valeur est enregistrée identiquement pour tous les utilisateurs, tous les profils, tous les dessins Avec les variables systèmes : la valeur peut être une chaîne de caractère avec ou sans espaces ou un nombre entier 16 bits, entier 32 bits ou réel avec une limite inférieure et/ou supérieure et ce nombre peut représenter un angle, une distance, une aire ou une valeur booléenne. la valeur peut ne pas être enregistrée ou bien être enregistrée par utilisateur, par profil ou par dessin -
Salut, Le dictionnaire "ACAD_LAYERFILTERS" n'est pas dans le dictionnaire des objets nommés (namedobjdict) il est (s'il y a bien des filtres de calque) dans le dictionnaire d'extension de la table des calques (LayerTable). PS: gc:DictDataList est une fonction aujourd'hui inutile qui était censée agir comme vlax-ldata-list.
-
Proposition d'un pense-bête pour les accès au registre Windows.
(gile) a répondu à un(e) sujet de DenisHen dans Pour aller plus loin en LISP
Un autre exemple avec une variable nommée "SOME_ANGLE", persistante par utilisateur, de type nombre réel (valeur angulaire) ((lambda (varName / rootKey) (setq rootKey (strcat "HKEY_CURRENT_USER\\" (vlax-user-product-key) "\\Variables\\" ) ) (foreach p '(("" "0.0") ; valeur par défaut ("PrimaryType" 5001) ; nombre réel ("SecondaryType" 5) ; valeur d'angle ("StorageType" 2) ; persiste par utilisateur ) (apply 'vl-registry-write (cons (strcat rootKey varName) p)) ) ) "SOME_ANGLE" ; nom de la variable ) Avec le type valeur angulaire, MODIFVAR utilise l'unité angulaire courante (getvar/setvar utilisent toujours les radians). Commande: (getvar 'some_angle) 0.0 Commande: (setvar 'some_angle (/ pi 6)) 0.523599 Commande: MODIFVAR Entrez le nom de la variable ou [?]: some_angle Entrez une nouvelle valeur pour SOME_ANGLE <30>: 180 Commande: (getvar 'some_angle) 3.14159 -
Proposition d'un pense-bête pour les accès au registre Windows.
(gile) a répondu à un(e) sujet de DenisHen dans Pour aller plus loin en LISP
On peut écrire dans le registre AutoCAD, mais comme toujours en programmation, il faut le faire prudemment. Par exemple, on peut depuis AutoCAD 2012, créer des variables système personnalisées en écrivant des clés dans la base de registre (En LISP on ne peut écrire que dans HKCU, donc les variables seront définies 'par utilisateur). Traduction de l'aide .NET pour le format des clés de variables système: [HKEY_CURRENT_USER\{ProductRegistryRoot}\Variables\{Nom de la variable}] @="{valeur par défaut}" : Requis, sera converti en PrimaryDataType "PrimaryType"=dword:{Type principal} : Requis "SecondaryType"=dword:{Type secondaire} : Optionnel "TypeFlags"=dword:{Drapeau de type} : Optionnel "StorageType"=dword:{Type de stockage} : Requis "Owner"="{Nom de l'application|exe}" : Optionnel "Range"="{minimum},{maximum}" : Optionnel, s'applique aux type principaux RTREAL, RTANG, RTSHORT et RTLONG "PrimaryType" RTREAL = 5001 Nombre réel RTSHORT = 5003 Nombre entier (16 bits) RTSTR = 5005 Chaîne de caractère RTLONG = 5010 Nombre entier (32 bits) "SecondaryType" Angle = 5 La variable représente une valeur angulaire. Area = 3 La variable représente un valeur d'aire. Valable uniquement lorsque le type principal est RTREAL Boolean = 1 La variable est un booléen. Valable uniquement lorsque le type principal est RTSHORT Distance = 4 La variable représente une valeur de distance. Valable uniquement lorsque le type principal est RTREAL Last = 6 Marque le dernier élément de l'énumération. None = 0 Aucun type de données secondaires n'est spécifié. SymbolName = 2 La variable est un nom de symbole RealDWG. Valable uniquement lorsque le type principal est RTSTR UnitlessReal = 6 La variable représente une valeur réelle sans unité. "StorageType" PerSession = 1 Etendue de l'application, ne persiste pas. PerUser = 2 Etendue de l'application, persiste par utilisateur. PerProfile = 3 Etendue de l'application, persiste par profil AutoCAD. PerDatabase = 4 Etendue du document, persiste dans le dessin. "TypeFlags" Chatty = 8 La variable envoie des notifications lorsqu'elle prend la même valeur que la précédente. Les variables ignorent normalement les tentatives de définir la même valeur deux fois de suite. DotMeansEmpty = 2 Le caractère . doit être interprété comme une chaîne vide. Valable uniquement lorsque le type principal est RTSTR None = 0 Aucun indicateur de type n'est spécifié. NoUndo = 4 La variable n'enregistre pas l'annulation. SpacesAllowed = 1 Les espaces sont autorisés dans les valeurs des variables. Valable uniquement lorsque le type principal est RTSTR Un exemple pour créer une variable système persistante dans le document, nommée "SOME_INTEGER", de type entier compris entre 0 et 15. ((lambda (varName / rootKey) (setq rootKey (strcat "HKEY_CURRENT_USER\\" (vlax-user-product-key) "\\Variables\\" ) ) (foreach p '(("" "0") ; valeur par défaut ("PrimaryType" 5003) ; nombre entier ("StorageType" 4) ; persiste dans le document ("LowerBound" 0) ; valeur minimale ("UpperBound" 15) ; valeur maximale ) (apply 'vl-registry-write (cons (strcat rootKey varName) p)) ) ) "SOME_INTEGER" ; nom de la variable ) La variable nouvellement créée est accessible avec les fonctions LISP setvar et getvar et avec la commande MODIFVAR. Commande: (getvar 'some_integer) 0 Commande: MODIFVAR Entrez le nom de la variable ou [?]: some_integer Entrez une nouvelle valeur pour SOME_INTEGER <0>: 42 Nécessite un entier entre 0 et 15. Entrez une nouvelle valeur pour SOME_INTEGER <0>: 7 Commande: (getvar 'some_integer) 7 Commande: (setvar 'some_integer -1) ; erreur: paramètre de la variable AutoCAD rejeté: SOME_INTEGER -1 Commande: (getvar 'some_integer) 7
