zebulon_ Posté(e) le 7 août 2007 Posté(e) le 7 août 2007 Bonjour, je me suis fait un lisp qui crée une cote où je remplace le texte de cote par défaut (par exemple 5000) par nombre*pas (par exemple 25*200) en faisant un textoverride sur l'objet cote. Sauf que, comme c'est maintenant une cote éditée, elle reste toujours à 25*200 même si on étire l'objet cote. Je me suis dit qu'avec les réacteurs je devrais y arriver, mais comme je n'y connais pas grand chose... Donc, je me suis dit que le plus simple serait d'attacher un object-reactor à l'objet cote, en rendant ce réacteur persistant (setq DimReactor (vlr-object-reactor (list E) "Dimension Reactor" '((:vlr-modified . test)))) (vlr-pers DimReactor) Où E est mon objet cote créé juste avant par le lisp et test ma fonction callback. Je pensais modifier la cote dans la fonction callback en faisant un nouveau textoverride, mais j'ai lu ceci dans l'aide de VLISP : Warning You cannot modify an object in a callback function if it is included in the object reactor's owner list. Attempts to do so will generate an error message and can cause AutoCAD to fail. Si je comprend bien, ce que je veux faire, à savoir modifier le texte d'une cote qu'on vient de modifier en mettant un nouveau nombre*pas, ne marchera pas de cette manière. Quelle est la démarche qui peut aboutir ?Merci. AmicalementZebulon_ C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
(gile) Posté(e) le 7 août 2007 Posté(e) le 7 août 2007 Salut _Zebulon, Je ne suis pas très fortiche avec les réacteurs, mais je me suis trouvé confronté à ce problème aussi.En fait, il semble que la fonction "CallBack" soit appelée avant que la modification de l'objet ne soit achevée.J'avais trouvé une issue en lançant dans la fonction callBack de l'Object-Reactor un Command-Reactor/:vlr-commandEnded qui lui, lance une fonction CallBack quand la commande est achevée, donc l'objet modifé. C'est un peu tiré par les cheveux mais ça semblait fonctionner. Bon courrage Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
zebulon_ Posté(e) le 7 août 2007 Auteur Posté(e) le 7 août 2007 Salut (gile), En fait, il semble que la fonction "CallBack" soit appelée avant que la modification de l'objet ne soit achevée. C'est ce qui me semble aussi. J'ai mis un simple (alert "coucou") dans la fonction callback et, comme la commande alert fige ce qui est affiché à l'écran, c'est toujours l'ancienne cote qui est affichée pendant l'exécution de la fonction callback et pas la cote modifiée. Pour le reste, va falloir que je me gratte la tête un peu... MerciAmicalementZebulon_ C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
Patrick_35 Posté(e) le 7 août 2007 Posté(e) le 7 août 2007 Salut Où E est mon objet coteou les objets ;) modifier le texte d'une cote qu'on vient de modifierDans le réacteur, le premier argument du réacteur est l'objet qui vient d'être modifié. Un vla-put-textoverride sur l'objet de la nouvelle valeur suffit.Une chose aussi à savoir, un (vlr-owners du deuxième argument du réacteur) retourne la liste des objets qui appartiennent au réacteur. Et d'après ce que je peux comprendre, tu fais un réacteur pas objet alors que tu as la possibilité de faire une liste d'objets par réacteur.Ensuite, tu utilises les persistants, ce qui implique que le lisp doit être chargé et transmis à ceux qui doivent travailler sur le dessin. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
zebulon_ Posté(e) le 7 août 2007 Auteur Posté(e) le 7 août 2007 Salut Patrick_35, (defun mafonction_callback (notifier-object reactor-object parameter-list)..... donc, je peux faire un vla-put-textoverride sur notifier-object ? Je vais essayer cela. J'utilise les persistants parce que je pensais que c'est le plus simple. Ceux à qui je transmet le fichier, s'ils modifient les cotes, elles ne seront pas rééditées automatiquement, comme elle pourront l'être chez moi. Je pense que ça n'a pas d'autre conséquence ou alors comment faire sinon ? Autre question :avec une cote existante comment savoir :- si un réacteur lui est rattaché ?- comment faire si je souhaite l'en débarrasser ? MerciAmicalementZebulon_ C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
Patrick_35 Posté(e) le 7 août 2007 Posté(e) le 7 août 2007 donc, je peux faire un vla-put-textoverride sur notifier-object ? Oui Ceux à qui je transmet le fichier, s'ils modifient les cotes, elles ne seront pas rééditées automatiquementOui, pas de mise à jour et des messages d'erreurs pour ceux qui modifient le dessin comment faire sinon ? En utilisant les vlax-ldata... si un réacteur lui est rattaché Normalement, avec vlr-added-p, mais je n'ai jamais utilisé - comment faire si je souhaite l'en débarrasser ? Pour un réacteur avec un objet, le plus simple est le vlr-remove et vlr-pers-release (pour les persistants)Pour un réacteurs avec plusieurs objets, avec le vlr-owner-remove @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
zebulon_ Posté(e) le 8 août 2007 Auteur Posté(e) le 8 août 2007 Merci pour les précisions. donc, je peux faire un vla-put-textoverride sur notifier-object ? cela me revoie un message d'erreurerreur: Erreur Automation Objet en cours de notification. Donc, il semblerait que le notifier-object n'est disponible qu'en lecture seule. Un vla-get fonctionne, mais un vla-put renvoie une erreur. En utilisant les vlax-ldata...Dans le principe, ça consiste à faire comment ? AmicalementZebulon_ [Edité le 8/8/2007 par zebulon_] C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
Patrick_35 Posté(e) le 8 août 2007 Posté(e) le 8 août 2007 cela me revoie un message d'erreurAh oui, exacte. Dans ce cas, il faut laisser tomber les réacteurs sur la modification de l'objet et utiliser ceux des commands. Je pense qu'autocad doit lui aussi écrire la valeur de la cote si elle n'est pas forcée et cela doit rentrer en conflit avec le réacteur de modification de l'objet qui lui aussi cherche à écrire la cote. Un exemple pour un objet lié au réacteur(defun test(obj cde) (if (member (car cde) (list "STRETCH" "PROPERTIES" "DDEDIT" "GRIP_STRETCH")) (vla-put-TextOverride (car (vlr-data obj)) "45") ; mettre la cote avec la valeur 45 ) (princ) ) (setq e (vlax-ename->vla-object (car (entsel)))) ; sélection de la cote (setq rea (vlr-command-reactor (list E) (list (cons :vlr-commandEnded (function test))))) ; création du réacteur (vlr-remove rea) ; pour effacer le réacteur Dans le principe, ça consiste à faire comment ?Les vlax-ldata... te permettent d'écrire des données directement dans le dessin comme une liste.J'utilise ce principe pour construire/gérer/détruire mes réacteurs.Par exemple, avec le lisp LATT, ma liste est construite de cette manière.La clé du vlax-ldata me permet de numéroter mes liaisons, donc mes réacteurs.L'élément suivant de préciser de type (pour le lisp), et donc pour le réacteur, le data (pas obligatoire).Ensuite vient le texte du premier attribut de la liste des objets qui sont attachés au réacteur.Puis, tout mes vla-objets.De cette manière, il est assez facile de retrouver ses petits.Utilise LATT et regarde un peu comment il fonctionne.Un (vlax-ldata-list "Patrick_35") te donnera une liste de tous les éléments.Un (vlax-ldata-get "Patrick_35" "0") te donnera la première chaîne de liaison et tu retrouveras la description que je viens de donner.Tu trouveras la routine (refaire_les_reacteurs_objet ...) qui construit les réacteurs d'après les vlax-ldata..., la routine (ajouter_suppr_obj_reacteur ...) pour ajouter/enlever un objet à un réacteur et la routine (effacer_les_reacteurs_objet ...) pour effacer le réacteur. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
zebulon_ Posté(e) le 8 août 2007 Auteur Posté(e) le 8 août 2007 Bonjour, j'avais fait ça entre temps. J'ai changé mon fusil d'épaule et, comme le suggérait (gile), j'ai regardé du côté des réacteurs de commande.Comme ce sont les commandes stretch et grip_stretch qui vont affecter la cote, je me suis dit qu'un réacteur de commande pouvait faire l'affaire. Cela donne quelque chose comme ça (vlr-command-reactor "Etirer Cotes" '((:vlr-commandEnded . EndStretchDimension))) (defun reacteur_modif_textecote (E) (if (vlax-property-available-p E "TextOverRide") (progn (setq OLDTEXT (vla-get-TextOverRide E)) (alert OLDTEXT) (setq MEASUREMENT (vla-get-measurement E)) (alert (rtos MEASUREMENT)) (vla-put-textOverRide E "ESSAI") ) ) ) (defun EndStretchDimension (calling-reactor endcommandInfo / thecommandend ss ename I) (setq thecommandend (nth 0 endcommandInfo)) (if (or (= thecommandend "STRETCH") (= thecommandend "GRIP_STRETCH")) (progn (if (not (setq SS (cadr (ssgetfirst)))) (setq ss (ssget "_P")) ) (setq I 0) (if ss (repeat (sslength ss) (setq ename (ssname ss I)) (if (= (x_trouvinfo "fac" ENAME "CADSYS") "COTEA") ;; quand j'ai créé la cote je lui ai mis un marqueur xdata pour la reconnaitre (Reacteur_modif_textecote (vlax-ename->vla-object ename)) ) (setq I (+ I 1)) ) ) ) ) ) ça à l'air de marcher. Maintenant, quand la cote est associative et qu'on modifie l'objet associé, la cote change aussi mais ce n'est pas elle qui est étirée. Donc, dans ce cas, ça ne marchera pas. Faut encore que je regarde ce que tu proposes(car (vlr-data obj))à la place du (ssget "_P") que j'utilise faute de mieux. AmicalementZebulon_ C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
zebulon_ Posté(e) le 8 août 2007 Auteur Posté(e) le 8 août 2007 C'est vraiment très fort les réacteurs... Merci pour le coup de main. AmicalementZebulon_ C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
Patrick_35 Posté(e) le 9 août 2007 Posté(e) le 9 août 2007 C'est vrai que l'on peut faire des choses impressionnantes avec les réacteursEn voici un qui me fait bien rire (defun autocad_qui_parle (texte / sapi) (setq sapi (vlax-create-object "Sapi.SpVoice")) (vlax-invoke sapi "Speak" texte 0) (vlax-release-object sapi) ) (defun autocad_qui_parle_debut (rea cde) (autocad_qui_parle (strcat "La commande ," (getcname (strcat "_" (car cde))) " commence")) ) (defun autocad_qui_parle_inconnu (rea cde) (autocad_qui_parle (strcat "Commande inconnu ," (car cde))) ) (defun autocad_qui_parle_cancel (rea cde) (autocad_qui_parle (strcat "La commande ," (getcname (strcat "_" (car cde))) " est abandonnée")) ) (defun autocad_qui_parle_failed (rea cde) (autocad_qui_parle (strcat "La commande ," (getcname (strcat "_" (car cde))) " est interrompue")) ) (defun autocad_qui_parle_fin (rea cde) (autocad_qui_parle (strcat "La commande ," (getcname (strcat "_" (car cde))) " est terminée")) ) (or pourrir_la_vie (setq pourrir_la_vie (vlr-command-reactor nil (list (cons :vlr-commandWillStart (function autocad_qui_parle_debut)) (cons :vlr-unknownCommand (function autocad_qui_parle_inconnu)) (cons :vlr-commandCancelled (function autocad_qui_parle_cancel)) (cons :vlr-commandFailed (function autocad_qui_parle_failed)) (cons :vlr-commandEnded (function autocad_qui_parle_fin)) ) ) ) ) (princ) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
zebulon_ Posté(e) le 9 août 2007 Auteur Posté(e) le 9 août 2007 pourrir_la_vie... Bien trouvé, comme nom de variable. J'imagine un bureau en open space avec trentaine de poste autocad où chacun y va de son "La commande machin commence" etc... En plus, tu passes pour un con si chacun entend "Commande inconnue"... Vaut mieux qu'autocad ne soit pas trop bavard. AmicalementZebulon_ C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme) C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)
Patrick_35 Posté(e) le 10 août 2007 Posté(e) le 10 août 2007 Vaut mieux qu'autocad ne soit pas trop bavard. Cela veux dire que l'on ne travaille pas trop ? ;) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant