-
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
-
Déterminer si un bloc se trouve à gauche ou à droite d'une polyligne
Luna a répondu à un(e) sujet de JPhil dans Pour aller plus loin en LISP
@Curlygoth, Je n'ai pas encore vraiment pris le temps pour comprendre parfaitement l'utilisation des données étendues et des dictionnaires, donc rien de ce que je dis sur ce sujet est une certitude pour le moment. Disons que les quelques lignes que j'ai pu comprendre et sur le fonctionnement supposée (modification de la liste DXF d'un objet), cela me semble cohérent que les données soient enregistrées dans le dessin vui. Je sais qu'il y a une différence entre les données étendues et les dictionnaires mais je ne sais pas exactement quoi... Edit: Bon du coup j'ai testé vite fait et vui les données étendues ajoutées via (vlax-ldata-put (car (entsel)) ...) sont enregistrées dans le dessin donc à partir du moment où on a ajouté une donnée étendue à un objet, on peut y accéder quand on veut ce qui permet de lier tout type de donnée à un objet (strings, bit-integer, valeur numériques, Entity name, ...). L'utilisateur n'a pas vraiment moyen d'accéder à ces données (sauf avec les ExpressTools : Tools > Attach Xdata / List Object Xdata), par contre pour la programmation cela permet de créer des applications plus évoluées et intelligentes. @didier, de ce que j'ai cru comprendre de sa démarche à ce niveau là, il préfère définir un sens non pas vis-à-vis du sens de construction de la polyligne mais plutôt du sens que l'utilisateur aura défini par la position des attributs A et Z. Autrement dit, même si géométriquement le point de départ de la polyligne est située au niveau de l'attribut Z, il faudra considérer que le sens de construction de la polyligne est inversé. Pour être honnête, j'ai un peu du mal avec ce principe, surtout lorsqu'on connaît l'existence de la fonction INVERSER (sélection d'UNE polyligne, clic droit > Polyligne > INVERSER) permettant de permuter l'ordre des sommets dans la liste DXF et donc le sens de construction de la polyligne. C'est pour cela que j'essaye de corriger plutôt l'utilisation d'un bloc de polyligne afin de ne plus utiliser ces attributs et privilégier naturellement le sens de la polyligne. Bisous, Luna -
Déterminer si un bloc se trouve à gauche ou à droite d'une polyligne
Luna a répondu à un(e) sujet de JPhil dans Pour aller plus loin en LISP
@JPhil, En vrai les données étendues c'est simple ! 😉 Autrement dit tu peux simplement faire : ((lambda (key value / crv val) (setq crv (car (entsel "\nSelect polyline : "))) (if (null (setq val (vlax-ldata-get crv key))) (setq val (vlax-ldata-put crv key value)) val ) )) Donc pour ton exemple tu peux définir la 'key' avec un string du genre "Nom" et 'value' tu définis "section 1 voie 1", "raccord n°XX" ou "truc mumuche" 😉 Ya pas plus simple pour ajouter une donnée étendue ou choper sa valeur existante. Et du coup c'est directement liée à l'objet sélectionné et c'est enregistré dans la liste DXF de l'objet donc si tu fermes/ré-ouvres le dessin, les données sont conservées (si je ne dis pas de bêtises). Convaincu ou il faut encore que je donne un autre exemple pour éviter l'utilisation de blocs à référence unique dans le seul et unique but de "nommer" une polyligne ? xD Bisous, Luna -
Déterminer si un bloc se trouve à gauche ou à droite d'une polyligne
Luna a répondu à un(e) sujet de JPhil dans Pour aller plus loin en LISP
Si c'est juste une histoire de nom, regarde plutôt du côté des données étendues et/ou gestion de dictionnaires, c'est bien plus pratique !! Je n'ai personnellement pas encore eut le temps d'étudier ce domaine de la programmation mais je comprends son fonctionnement donc cela devrait être la solution que tu recherches pour te simplifier la vie en temps que développeur ET d'utilisateur 😉 Bisous, Luna -
Déterminer si un bloc se trouve à gauche ou à droite d'une polyligne
Luna a répondu à un(e) sujet de JPhil dans Pour aller plus loin en LISP
Coucou, Alors je pense ne pas avoir compris parfaitement le problème... Tu n'as que des blocs dans ton histoire, aucune ligne ou polyligne ? Car tu as tes blocs de signalisation, qui sont donc des blocs et on veut savoir de quel côté ils se trouvent et tu as le bloc chemin, qui du coup est aussi un bloc... Pourquoi faut-il un bloc pour le chemin au lieu d'une polyligne basique...? Dans le cas d'un chemin à base d'une polyligne je prendrais ceci : ((lambda (/ crv blk ptb ptc prm i pta ptz ang bng) (setq crv (car (entsel "\nSelect polyline : ")) blk (car (entsel "\nSelect block : ")) ptb (cdr (assoc 10 (entget blk))) ptc (vlax-curve-getClosestPointTo crv ptb) prm (vlax-curve-getParamAtPoint crv ptc) i (fix prm) pta (vlax-curve-getPointAtParam crv i) ptz (vlax-curve-getPointAtParam crv (1+ i)) ang (angle pta ptz) bng (angle ptc ptb) ) (cond ((equal (- bng ang) (/ pi 2.) 1e-15) "left") ((equal (- bng ang) (/ (* 3.0 pi) 2.) 1e-15) "right") ) )) Évidemment on peut simplifier l'écriture, etc mais c'est juste à titre d'exemple, je ferais quelque chose comme cela perso. Si je devais traduire mathématiquement parlant, je dirais qu'il suffit de calculer l'angle entre la normale induite par le bloc projeté sur ta courbe et l'angle de ton segment. Pour être encore plus dans le vrai, il ne faudrait pas utiliser le PointAtParam mais plutôt la FirstDeriv pour pouvoir également gérer les courbes d'une polyligne/spline. Bisous, Luna -
Pour le principe de la forme, en AutoLISP on peut utiliser ceci pour copier des attributs entre deux références de blocs (quelque soit le nom du bloc, il faut juste donner le nom de l'étiquette pour la source et l'étiquette cible : (defun copy-Att (blk-src tag-src blk-tgt tag-tgt / ConvEnt get-att-list check LM:vl-SetAttributeValue value) (defun ConvEnt (name flag / tp) (if (= (setq tp (type name)) flag) name (apply (read (strcat "vlax-" (vl-symbol-name tp) "->" (vl-symbol-name flag))) (list name)) ) ) (defun get-att-list (name) (mapcar '(lambda (a) (cons (vla-get-tagstring a) (vla-get-textstring a))) (vlax-invoke (ConvEnt name 'VLA-OBJECT) 'getAttributes)) ) (defun check (blk tag / att value) (and (= "AcDbBlockReference" (vla-get-ObjectName (ConvEnt blk 'VLA-OBJECT))) (setq att (get-att-list blk)) (assoc tag att) (setq value (cdr (assoc tag att))) ) value ) (defun LM:vl-SetAttributeValue (blk tag val) (setq tag (strcase tag)) (vl-some '(lambda (att) (if (= tag (strcase (vla-get-tagstring att))) (progn (vla-put-textstring att val) val) ) ) (vlax-invoke blk 'getAttributes) ) ) (and (setq value (check blk-src tag-src)) (check blk-tgt tag-tgt) (LM:vl-SetAttributeValue (ConvEnt blk-tgt 'VLA-OBJECT) tag-tgt value) ) ) Un exemple d'utilisation simple : (copy-att (car (entsel "\nSource : ")) "MODIFICATIONS_IND_A" (car (entsel "\nCible : ")) "MODIFICATIONS_IND_B") Les arguments 'blk-*' peuvent aussi bien correspondre à l'Entity name de la référence de bloc qu'au VLA-Object de cette même référence. J'ai essayé de programmer en Visual LISP afin que cela se rapproche le plus possible du langage VBA. Evidemment il s'agit d'une méthode généralisée et non adaptée à ta demande précisément, cependant cela peut te donner des pistes de recherches. Je verrais si j'ai un peu de temps dans la semaine pour regarder de plus près ta problématique. Je maintiens tout de même qu'il serait plus simple de créer un programme pour créer les indices de modification au lieu de les copier... Bisous, Luna
-
Non on travaille via VPN. Donc en effet de temps à autres la connexion est un peu compliquée...mais chat n'empêche pas forcément de travailler sur AutoCAD ou autre logiciel, cela empêche juste de sauvegarder sur le serveur ou d'avoir accès aux fichiers non ouverts... Après j'utilise mon compte OneDrive pour avoir un bureau commun entre mes deux PC. Honnêtement je n'ai pas eut de grosse coupure jusqu'à présent, cela peut bloquer au maximum 1 journée mais pas plus...(bon si le plus violent c'était en décembre 2020, on a eut droit à un rollback des serveurs de 3 jours de travail c'était pas gentils...!) Bisous, Luna
-
Le sujet commence donc à se préciser. On a donc une seule définition de bloc concernée, mais ses références doivent se trouver dans des présentations différentes. Le but étant de gérer les modifications d'indices dans un cartouche. Plusieurs questions me viennent à l'esprit dans ce cas : Combien de références de bloc "CARTOUCHE" as-tu sur chacune de tes présentations ? As-tu un seul et unique bloc "CARTOUCHE" par présentation ou bien peux-tu en avoir plusieurs ? Pourquoi créer un programme qui copie les valeurs d'un cartouche vers un autre au lieu de créer un cartouche qui crée les indices de plusieurs cartouches en même temps ? Ainsi au lieu de devoir définir un cartouche source dans un premier temps puis de copier ses valeurs vers d'autres, tu définis en une fois les valeurs du cartouche source et des cartouches cibles. Peut-on avoir un .dwg d'exemple pour savoir sur quoi travailler précisément ? Je repose la question : VBA uniquement ou bien on peut faire de l'AutoLISP/DCL ? Bisous, Luna
-
Coucou, Je dirais qu'il est reconnu dans les contraintes matérielles essentiellement. Mais vui, je doute qu'il y ait beaucoup de boîtes qui fourni le double de matériel par personne dans ces cas là. Après il s'agit également d'un concours de circonstances ! Notre service IT a commandé de nouvelles tours pour le pôle CAO car les anciennes commençait à se faire vieille et la config' aussi. Les nouvelles tours sont arrivées juste avant le premier confinement en mars 2020, du coup on a pu installer les nouvelles tours au bureau comme prévu et on a conservé nos anciennes pour les utiliser à la maison. Cela aurait été différent je pense si cette commande n'avait pas été faite et n'était pas arrivée à ce moment ! Bisous, Luna
-
Coucou, Pour le moment je suis à 2j de télétravail. Mais c'est une société de plus de 350 employés donc on a réussi pour le pôle CAO à conserver notre matériel sur place (1 tour, 2 écrans, clavier/souris) et d'avoir un poste à l'identique à la maison (1 tour, 2 écrans, clavier/souris) ce qui nous évite d'avoir à déménager tout ce bordel tous les 2 jours... Par contre on est les seuls dans ce cas là, le reste de la boîte travaille avec des PC donc ils peuvent se les trimballer plus facilement, ils ont juste droit aux écrans qui restent chez eux il me semble. Donc pour le coup on est plutôt bien loti car on n'a pas besoin de se soucier du matériel tous les matins. Et AutoCAD tourne mieux sur des tours avec les bonnes config que sur des PC. Bisous, Luna
-
Coucou, VBA uniquement ? Autrement il faudrait être un peu plus précis quand au nom des attributs et surtout si les noms des attributs sont les mêmes pour les deux blocs... Mais la réponse est forcément oui (par contre si c'est VBA exclusivement, je laisse les personnes à même de répondre poster les infos). Bisous, Luna
-
Bonne année et bonnes fêtes ! Bisous, Luna
-
Comme c'est expliqué, la liste (list 5 "1 2 3 4 5 6 7") correspond ni plus ni moins aux arguments de (initget). En clair il faut écrire le programme avec (list 5 "1 2 3 4 5 6 7") mais le programme lorsqu'il l'exécute il va faire l'équivalent de ceci (initget 5 "1 2 3 4 5 6 7") J'ai absolument rien compris...La programmation a peut-être un petit côté magique, mais certainement pas à ce point ! Si j'ai compris tu voudrais que la couleur du texte corresponde à la valeur de couleur genre : Car si c'est bien cela ta demande, c'est impossible ! Il s'agit d'une option non dépendante d'une variable système et qui ne peut pas prendre plusieurs valeurs différentes pour une même invite ! Donc la réponse est tout bonnement non, commence déjà par lire TOUS les liens que l'on t'a donné @JPhil et moi pour comprendre comment écrire un programme et comment commencer en bas de l'échelle. Comme c'est écrit dans mes messages, c'est surtout à titre d'amusement que j'ai écrit ces programmes et pour te montrer que l'on peut faire des programmes relativement complexes en assez peu de lignes. Cela peut également te servir d'exemple sur le fonctionnement d'un programme et répondre à certaines de tes questions (si tu cherches suffisamment tu finiras par comprendre). Il peut aussi servir à toi comme à d'autre comme programme tout fait pour modifier des propriétés d'objets. Bref, il peut être utile de bien des manières mais cela ne signifie aucunement que tu vas apprendre l'AutoLISP plus vite en l'utilisant ^^" Je pensais l'avoir répété suffisamment mais à priori non : lis TOUS les liens de cours que l'on t'a donné et dans leur INTEGRALITE. Si tu veux les lire 2 fois, 3 fois, voire plus, il n'y a aucun problème ! Mais je pense que poser des questions avant de s'instruire n'est pas la bonne solution pour comprendre. Bref essaye déjà de construire tes propres commandes / fonctions par toi même à partir de ce que tu as compris dans le cours et si tu penses que tu peux l'améliorer ou bien si chat ne fonctionne pas, réessaye autrement. Si au bout de la dixième voire vingtième fois que tu essayes autrement tu n'as toujours pas de résultats satisfaisant, tu peux poser des questions. Elles s'avèreront un peu plus construite et réfléchie car j'ai vraiment l'impression de tourner en rond et qu'à chaque modification apportée, tu effaces le reste et tu oublies tout ce qui a été fait auparavant... Si les programmes que tu veux faire sont trop complexes à mettre en place, alors essaye avec quelques chose de plus simple. Même un programme bidon qui te sert strictement à rien. Mais au moins tu comprendras peut-être plus facilement les notions de base. PS: désolée si je semble agressive ou méchante, ce n'est pas mon intention. Je suis juste frustrée de voir une personne qui se dit vouloir apprendre à programmer mais qui veut tout faire bien tout de suite et du coup ne prend pas le temps nécessaire pour simplement lire. Un écrivain avant d'écrire son tout premier livre, il a passé des années à lire d'autres livres, à lire des cours sur l'écriture, à prendre des cours sur la langue française, à renflouer son vocabulaire lyrique, etc... Et après toutes ces années non pas d'écriture mais de lecture pure et simple, il a fait des essais. Pleins d'essais de quelques pages pour commencer, puis il réfléchit à un personnage, une histoire, il essaye d'ajouter le plus de détails possible pour essayer d'écrire un peu plus de 20 pages. Bref Rome ne s'est pas construite en 2 jours, les best-sellers non plus et les programmes non plus. Donc prend juste le temps et tu verras que toutes tes questions que tu te poses à chaud trouveront très vite une réponse si tu prends toi-même le temps d'y réfléchir. Bisous, Luna
-
Du coup si tu veux essayer de tester ta version avec LineTypeScale et LineWeight, tu peux utiliser ceci pour 'pplst' : (setq pplst (list (cons "ecHelle" (list "LineTypeScale" (list 7) (list 'getreal))) (cons "ePaisseur" (list 'LineWeight (list 5 "DuCalque 0 5 9 13 15 18 20 25 30 35 40 50 53 60 70 80 90 100 106 120 140 158 200 211") (list 'getreal))) ; ... ) filter (cond ( (cons "\nSélectionner une ligne" "LINE,AcDbLine" ) ) ( (cons (getstring T "\nDéfinir un message de sélection : ") (getstring T "\nDéfinir un pattern pour le filtre de sélection : ") ) ) ) ) Tu peux modifier le filtre s'il ne te convient pas également car ici seuls les objets LIGNE sont pris en compte, donc les POLYLIGNES ne sont pas sélectionnable par exemple. Et puis tu me diras si chat marche chez toi ou non 😉 Bisous, Luna
-
Pour info, pourquoi ta commande pour les épaisseurs de ligne utilise des nombres décimaux alors que les valeurs de la propriété sont conservées en mm ? Il faudrait plutôt tout multiplier par 100 si tu veux que chat marche, ou alors mettre directement dans ton (initget) les valeurs en mm au lieu de faire un cond avec la liste... Bisous, Luna
-
Bon encore une fois pour le fun, voici une commande facilement modifiable pour pouvoir modifier toutes les propriétés que tu souhaites pour les objets que tu souhaites. La seule chose qu'il faut comprendre correctement c'est la structure de la variable 'pplst' car c'est cette liste qui construit l'ensemble de la commande. En revanche on peut ajouter autant de ligne qu'on le souhaite ! 😉 (defun c:MOD_OBJ (/ lst2str pplst filter choice ppname ptype ppvalue ent) (defun lst2str (lst sep) (vl-string-left-trim sep (apply 'strcat (mapcar '(lambda (l) (strcat sep (vl-princ-to-string l))) lst))) ) (setq pplst (list (cons "ecHelle" (list "LineTypeScale" (list 7) (list 'getreal))) (cons "ePaisseur" (list 'LineWeight (list 5 "DuCalque 0 5 9 13 15 18 20 25 30 35 40 50 53 60 70 80 90 100 106 120 140 158 200 211") (list 'getreal))) (cons "Calque" (list 0 (list 1 (getvar 'CLAYER)) (list 'getstring T))) ; ... ) filter (cond ( (cons "\nSélectionner une ligne" "LINE,AcDbLine" ) ) ( (cons (getstring T "\nDéfinir un message de sélection : ") (getstring T "\nDéfinir un pattern pour le filtre de sélection : ") ) ) ) ) (while (progn (initget (lst2str (mapcar 'car pplst) " ")) (setq choice (cond ((getkword (strcat "\nVeuillez choisir la propriété à modifier [" (lst2str (mapcar 'car pplst) "/") "] <Quitter> : " ) ) ) ) ) ) (setq ppname (cadr (assoc choice pplst)) ptype (type ppname) ) (apply 'initget (caddr (assoc choice pplst))) (setq ppvalue (apply (car (cadddr (assoc choice pplst))) (vl-remove nil (list (cadr (cadddr (assoc choice pplst))) (strcat "\nSpécifiez la nouvelle valeur de la propriété " (strcase choice) (if (= (type (last (caddr (assoc choice pplst)))) 'STR) (strcat " [" (vl-string-translate " " "/" (last (caddr (assoc choice pplst)))) "]") "" ) " : " ) ) ) ) ) (while (/= (progn (initget "Quitter") (setq ent (entsel (strcat (car filter) " [Quitter] : ")))) "Quitter") (cond ((null ent)) ((SetAnyProperty (car ent) (cdr filter) (cond ((= ptype 'INT) 0) ((= ptype 'STR) 1) ((= ptype 'SYM) 2)) ppname ppvalue) (princ (strcat "\nLa propriété \"" (vl-prin1-to-string ppname) "\" possède désormais la valeur \"" (vl-prin1-to-string ppvalue) "\" pour l'objet \"" (cdr (assoc 0 (entget (car ent)))) "\"." ) ) ) (T (princ (strcat "\nEchec lors de la modification de la propriété \"" (vl-prin1-to-string ppname) "\" pour l'objet \"" (cdr (assoc 0 (entget (car ent)))) "\"." ) ) ) ) ) ) (princ) ) Voici un exemple d'une ligne de 'pplst', pour ajouter ou enlever une liste, il suffit de copier le modèle ou une existante ou simplement de la supprimer : Modèle : (cons Keyword (list PropertyName (list [bits] [keyword]) (list 'GetFunction [pt,cr]) ) ) Avec : --• Keyword = correspond au mot clé affiché lors de la sélection d'une propriété dans la liste du premier (initget), les règles propres à (initget) concernant les mots clés s'applique à cette chaîne de caractères. --• PropertyName = correspond au nom de la propriété. Le type permet d'identifier s'il s'agit d'une propriété DXF (= integer), d'une propriété ActiveX (= string) ou d'une propriété Visual (= symbol quoté). --• [bits] = correspond à l'argument [bits] du second (initget), donc optionnel, pour la nouvelle valeur de propriété --• [keyword] = correspond à l'argument [keyword] du second (initget), donc optionnel, pour la nouvelle valeur de propriété --• 'GetFunction = correspond au nom de la fonction (get...) quotée, donc seules les valeurs suivantes sont fonctionnelles : 'entsel, 'getangle, 'getcorner, 'getdist, 'getint, 'getkword, 'getorient, 'getpoint, 'getreal, 'getstring or 'nentsel --• [pt,cr] = correspond à l'argument optionnel de certaines fonctions (get...), ou obligatoire, situé avant l'argument 'msg' Il ne faut surtout pas supprimer une liste, même pour une liste vide (list), autrement le programme ne fonctionnera pas ! Il faut donc se renseigner sur les propriétés existantes d'un objet grâce aux fonctions (entget), (dumpallproperties) et (vlax-dump-object) ! Exemple d'utilisation : (cons "ePaisseur" ;; Nom à afficher pour le premier (initget) de sélection des propriétés (list 'LineWeight ;; Nom de la propriété (ici, il s'agit d'une propriété Visual) (list 5 "DuCalque 106 120 140 158 200 211") ;; arguments du second (initget) de nouvelle valeur (list 'getreal) ;; fonction (get---) suivant le second (initget) afin de définir le type de valeur attendu ) ) La seconde variable qui peut également avoir de l'importance, c'est 'filter' car il s'agit de la variable permettant d'ajouter un filtre sur le type d'objet sélectionnable ainsi que le message à afficher lors de la sélection. Il est conseillé de définir un filtre avec la valeur DXF et sont équivalent Visual pour ne pas avoir de soucis suivant le type de propriété à redéfinir. Si l'on préfère que l'utilisateur définisse par lui même le filtre et le message à afficher, il suffit de mettre la partie (cons "\nSélectionner une ligne" "LINE,AcDbLine" ) en format commentaire : ; (cons ; "\nSélectionner une ligne" ; "LINE,AcDbLine" ; ) Normalement, seules ces deux variables sont modifiables à volonté et le reste de la commande s'adaptera au ajout/suppression de lignes de propriété ou modification du filtre d'objet. Pour qu'elle fonctionne elle a besoin de la fonction ci-dessous (qui correspond justement à la version généralisée de (SetObjectsProperty) en sortant la sélection d'objet de la fonction) : (defun SetAnyProperty (name search flag key value / getName setProperty) (defun getName (name flag) (cond ((= flag 0) (cdr (assoc 0 (entget name)))) ((= flag 1) (vla-get-ObjectName (vlax-ename->vla-object name))) ((= flag 2) (vla-get-ObjectName (vlax-ename->vla-object name))) ) ) (defun setProperty (name flag key value) (cond ((= flag 0) (vl-catch-all-apply 'entmod (list (if (assoc key (entget name)) (subst (cons key value) (assoc key (entget name)) (entget name)) (append (entget name) (list (cons key value))) ) ) ) ) ((= flag 1) (if (listp key) (vl-catch-all-apply 'setpropertyvalue (append (list name) key (list value))) (vl-catch-all-apply 'setpropertyvalue (list name key value)) ) ) ((= flag 2) (vl-catch-all-apply 'vlax-put (list (vlax-ename->vla-object name) key value))) ) ) (and name (wcmatch (strcase (getName name flag)) (strcase search)) (not (vl-catch-all-error-p (setProperty name flag key value))) ) ) Voili voilou ! Have fun 🙂 Bisous, Luna
-
@(gile), Je sais que la balise 'Code <> permet d'empêcher cette mise en forme, cependant ce n'est pas forcément du code où j'ai besoin d'écrire ces termes. Cela peut être simplement du texte ou une citation...Car le souci de la balise 'Code' c'est qu'elle ajoute un retour chariot, une mise en forme, etc... or si je veux écrire (bit 8 ), je pense ne pas avoir besoin d'utiliser la balise 'Code' pour pouvoir le faire et ce serait plus simple que de devoir rajouter des caractères en plus pour "couper" cette détection auto... L'autre solution serait d'écrire 100% de mes messages dans une balise 'Code', mais dans ce cas, comment différencier la partie réellement 'Code' du simple texte puisque je ne peux pas insérer une balise dans une balise 'Code'. Donc cela serait le bordel
-
Théoriquement il faut le mettre à 5 pour l'échelle, et 4 pour l'épaisseur ! Car je n'ai jamais vu une échelle nulle pour ma part... Bisous, Luna
-
Coucou, Je ne suis probablement pas la seule (ou bien je n'ai pas encore trouvé l'option) mais je trouve cela quelque peu frustrant la détection automatique des écritures textuelles d’émoticônes. Car au final il y a plusieurs écritures textuelles qui ne peuvent tout simplement plus exister sous forme de texte car elles sont automatiquement remplacées par des émojis...! Or ces chaînes de caractères sont souvent utiles/nécessaire en temps que texte, sans même avoir envie ou savoir que cela soit remplacer par un émoticône ! Par exemple les 😎 (= huit+parenthèse_fermante), 😄 (= c+deux_points), ... Serait-il possible de mettre ce formatage automatique comme une option, afin que l'on puisse l'activer ou le désactiver à volonté, ou bien cela est trop complexe à mettre en place ? Bisous, Luna
-
Théoriquement, il n'y a pas besoin de spécifier le 25 comme keyword dans le (initget). AutoCAD détecte automatiquement une valeur écrite entre "<...>" et pré-rempli le champ dans le cas ou la variable DYNMODE est activée. Autrement, pour les valeurs négatives, je crois qu'il y a encore quelque chose que tu n'as pas bien compris à propos d'initget...Je te laisse relire l'aide ci-dessous : Bisous, Luna
-
Généralement pour les valeurs par défaut, il s'agit de valeurs pouvant être sélectionner directement avec ENTER (ou SPACE). Autrement dit il ne s'agit pas d'un keyword mais plus une affectation de valeur dans le cas d'une entrée à vide. Pour que cela fonctionne, il faut non seulement autoriser l'utilisateur à faire une entrée à vide mais aussi tester si le retour de la fonction (get---) retourne 'nil', alors il faut lui affecter la valeur par défaut (ici 25). Cela te suffit pour comprendre la démarche ou bien faut-il que je donne la réponse directement ? Pour info, si tu analyses logiquement mon explication, tu as toutes les billes pour écrire cette partie, aussi bien dans le déroulement des fonctions que le nom des fonctions à utiliser... Bisous, Luna
-
Juste pour l'exemple de généralisation d'une fonction : (defun SetObjectsProperty (msg search flag PpName value / f ent) (defun f (flag / ent PpName value) (cond ((= flag 0) ;; Propriétés DXF via (entget) (cons (quote (cdr (assoc 0 (entget ent)))) (quote (if (assoc PpName (entget ent)) (entmod (subst (cons PpName value) (assoc PpName (entget ent)) (entget ent))) (entmod (append (entget ent) (list (cons PpName value)))) ) ) ) ) ((= flag 1) ;; Propriétés ActiveX via (dumpallproperties) (cons (quote (vla-get-ObjectName (vlax-ename->vla-object ent))) (quote (setpropertyvalue ent PpName value)) ) ) ((= flag 2) ;;Propriétés Visual LISP via (vlax-dump-object) (cons (quote (vla-get-ObjectName (vlax-ename->vla-object ent))) (quote (vlax-put (vlax-ename->vla-object ent) PpName value)) ) ) ) ) (while (and (setq ent (apply 'entsel (if msg (list msg)))) (setq ent (car ent)) (wcmatch (strcase (eval (car (f flag)))) (strcase search)) ) (eval (cdr (f flag))) ) ) Avec les arguments : msg -> correspond au message afficher par la fonction (entsel) (type msg) = 'STR | Ex. : "\nSélectionnez la ligne :", "\nSélectionner un cercle :", nil, ... search -> correspond au filtre que l'on souhaite appliquer pour le type d'objet grâce à (wcmatch). Pour ne pas appliquer de filtre, mettre "*" (type search) = 'STR | Ex. : "LINE", "line", "*Line", "*", "ARC,*LINE,CIRCLE", ... flag -> correspond au type de propriété que l'on souhaite modifier entre DXF, ActiveX et Visual LISP (type flag) = 'INT | flag = 0, la variable 'search' sera comparée au code DXF 0 de l'objet sélectionné, la variable 'PpName' correspond au code DXF de la propriété dispo dans la liste DXF (cf. (entget) pour connaître les propriétés dispo d'un objet) flag = 1, la variable 'search' sera comparée à la propriété Visual "ObjectName" de l'objet sélectionné, la variable 'PpName' correspond au nom de la propriété ActiveX (cf. (dumpallproperties) pour connaître les propriétés) flag = 2, la variable 'search' sera comparée à la propriété Visual "ObjectName" de l'objet sélectionné, la variable 'PpName' correspond au nom de la propriété Visual quotée (cf. (vlax-dump-object) pour connaître les propriétés) PpName -> correspond au nom de la propriété qui doit être modifiée. Selon la valeur de 'flag', le type de PpName est différent Si flag = 0, alors (type PpName) = 'INT | Ex. : 8, 48, 50, 62, ... Si flag = 1, alors (type PpName) = 'STR | Ex. : "LineTypeScale", "LineWeight", "LayerID", ... Si flag = 2, alors (type PpName) = 'SYM | Ex. : 'LineTypeScale, 'LineWeight, 'Transparency, ... value -> correspond à la nouvelle valeur que l'on souhaite appliquer à la propriété 'PpName'. Le type de 'value' est donc dépendant du type de valeur défini par la propriété (type value) = ... | Ex. : 23.42, "Calque1", 2, ... Un exemple d'utilisation : (defun c:ECH_EP_LIGNE (/ choix) (initget "? ecHelle ePaisseur eXit") (setq txt "\nSélectionner une ligne :" ;; Pour définir un message commun pour les deux propriétés s "*LINE" ;; Pour définir un filtre commun pour les deux propriétés choix (cond ((getkword "\nEnter an option [ecHelle/ePaisseur] <eXit> : ")) ;; Demande à l'utilisateur la propriété à changer ("eXit") ) ) (cond ((= choix "?") (princ "...") ;; Texte d'aide à afficher ! ) ((= choix "ecHelle") (SetObjectsProperty txt s 2 'LineTypeScale (progn (initget 7) (getreal "\nQuelle échelle : "))) ) ((= choix "ePaisseur") (SetObjectsProperty txt s 2 'LineWeight (progn (initget 7) (getint "\nQuelle épaisseur : "))) ) ) (princ) ) Evidemment c'est uniquement à titre d'exemple, personne s'attends à sortir ce genre de fonctions durant l'apprentissage. Le but ici est de montrer qu'en créant des fonctions ayant une utilisation plus globale, on peut démultiplier leur utilisation dans d'autres programmes sans jamais avoir besoin de les modifier. Plus elles sont un fonctionnement généralisé, et plus leur domaine d'application est étendu. Donc par exemple celle-ci permet de modifier n'importe quelle propriété d'objet en bouclant la sélection avec un (while). Une généralisation de cette fonction serait bien entendu de sortir la boucle (while) de la fonction de modification de propriété car on préfère toujours mettre un nom d'objet en argument de fonction pour pouvoir l'utiliser aussi bien avec ou sans intervention utilisateur. 😉 Bisous, Luna
-
Coucou, Tu peux éventuellement mettre une majuscule pour "echelle" et "epaisseur" dans les fonctions (initget) et (getkword), comme par exemple "ecHelle" et "ePaisseur", comme chat il suffit d'écrire "H" pour "echelle" et "P" pour "epaisseur". Ensuite dans les améliorations possible c'est à chaque fois que tu fais quelque chose plusieurs fois, alors tu peux créer une fonction pour cela pour n'avoir à le définir qu'une seule fois. Et à quoi sert l'option "?", normalement elle permet d'afficher un texte d'aide pour l'utilisation de la commande/fonction mais ici, elle semble ne servir à rien...^^" Bisous, Luna
-
Coucou, Tu as répondu à ta propre question en une seule ligne : Il faut appeler les FONCTIONS pour que cela fonctionne. (retourne voir le message contenant un extrait du cours de (gile) que j'ai mis un peu plus tôt concernant la fonction (defun) !!!) Car je n'ai pas l'impression de donner de simples pistes de recherche mais plutôt des réponses, en boucle >n< Par contre tu feras attention, ton (getkword) est récupéré par la variable 'chosen', puis ton (cond) évalue la valeur de la variable 'choix', donc j'ai bien peur que ton programme ne fonctionne tout simplement pas... Une autre erreur dans la fonction (initget) et (getkword) : les lettres majuscules définissent les alias clavier pouvant être utilisé par l'utilisateur pour choisir son mot clé. Donc si deux réponses différentes possèdent la même lettre majuscule, seule la première réponse dans l'ordre de l'initget est considérée pour les deux réponses. Autrement dit, dans ton cas, si je réponds "E" alors le programme me renvoie 'chosen' = "Echelle", si je clique sur "Echelle" alors le programme me renvoie 'chosen' = "Echelle" et si je clique sur "Epaisseur" alors le programme me renvoie 'chosen' = "Echelle"... Bisous, Luna
-
(defun c:ECH_LIGNE (/ echelle e) (initget 7) (setq echelle (getreal "\nQuelle échelle : ")) (while (and (setq e (car (entsel "\nSélectionner une ligne :"))) (wcmatch (cdr (assoc 0 (entget e))) "*LINE")) (setpropertyvalue e "LinetypeScale" echelle) ) (princ) ) ou (defun c:ECH_LIGNE (/ echelle e) (initget 7) (setq echelle (getreal "\nQuelle échelle : ")) (while (and (setq e (car (entsel "\nSélectionner une ligne :"))) (wcmatch (cdr (assoc 0 (entget e))) "*LINE")) (if (assoc 48 (entget e)) (entmod (subst (cons 48 echelle) (assoc 48 (entget e)) (entget e))) (entmod (append (entget e) (list (cons 48 echelle)))) ) ) (princ) ) ou (defun c:ECH_LIGNE (/ echelle e) (initget 7) (setq echelle (getreal "\nQuelle échelle : ")) (while (and (setq e (car (entsel "\nSélectionner une ligne :"))) (wcmatch (cdr (assoc 0 (entget e))) "*LINE")) (vla-put-LineTypeScale (vlax-ename->vla-object e) echelle) ) (princ) ) Bisous, Luna
-
Coucou @Netparty, Ci-dessous la partie issue du site Introduction à AutoLISP de (gile) concernant la déclaration des variables : Cela te permettra sûrement de mieux comprendre le pourquoi j'ai dit qu'il est important de connaître cela 🙂 Car chat peut causer de nombreux problèmes sur la programmation, surtout lorsqu'on a plusieurs commandes/fonctions et que certaine variables sont communes (notamment les constructions de liste via (cons) !). Selon tes besoins, il est possible que la variable CELTSCALE n'ai pas besoin d'être mise à jour. Car d'après ta demande initiale : Pour moi je le comprends comme "seules les lignes sur lesquelles je clique durant la commande doivent être modifiées" et non comme "seules les lignes sur lesquelles je clique durant la commande et les nouvelles lignes crées à l'avenir doivent avoir la nouvelle échelle". Or en définissant CELTSCALE (ou LTSCALE), cela implique uniquement les nouvelles entités et non les existantes. Cela commence à devenir complexe de te donner des pistes de recherche sans te donner l'exemple de code si tu ne regardes déjà pas les pistes que l'on te propose... Commence par lire les liens des sites de cours que je t'ai donné, lit les jusqu'au bout et tu comprendras que toutes les questions que tu te/nous poses sont déjà dans ces documents. Si après les avoir lu, il y a toujours quelques incompréhensions revient nous voir on pourra t'aider plus facilement. Bisous, Luna
