Aller au contenu

Aide premier Lisp


Messages recommandés

Posté(e)

Re à tous

Comme je suis lancé voici ma version pour les épaisseurs de ligne :

(defun c:EP_LIGNE (/ epaisseur e)
	
	 
	(initget "DuCalque 0.00 0.05 0.09 0.13 0.15 0.18 0.20 0.25 0.30 0.35 0.40 0.50 0.53 0.60 0.70 0.80 0.90 1.00 1.06 1.20 1.40 1.58 2.00 2.11") 
	
  (setq
   epaisseur (cdr
 (assoc	(getkword
	  "\nEpaisseur [DuCalque/0.00/0.05/0.09/0.13/0.15/0.18/0.20/0.25/0.30/0.35/0.40/0.50/0.53/0.60/0.70/0.80/0.90/1.00/1.06/1.20/1.40/1.58/2.00/2.11] <0.00> : "
	)
	'((nil . 0)
	  ("DuCalque" . -1)
	  ("0.00" . 0.00)
    ("0.05" . 5)
    ("0.09" . 9)
    ("0.13" . 13)
    ("0.15" . 15)
    ("0.18" . 18)
    ("0.20" . 20)
    ("0.25" . 25)
    ("0.30" . 30)
    ("0.35" . 35)
    ("0.40" . 40)
    ("0.50" . 50)
    ("0.53" . 53)
    ("0.60" . 60)
    ("0.70" . 70)
    ("0.80" . 80)
    ("0.90" . 90)
    ("1.00" . 100)
    ("1.06" . 106)
    ("1.20" . 120)
    ("1.40" . 140)
    ("1.58" . 158)
    ("2.00" . 200)
    ("2.11" . 211)

	  
	 )
 )
      )
 )
 
	(while (and (setq e (car (entsel "\nSélectionner une ligne :"))) (wcmatch (cdr (assoc 0 (entget e))) "*LINE"))
		(vla-put-lineweight (vlax-ename->vla-object e) epaisseur)
	)
	(princ)
)

Cela fonctionne mais j'ai quand même une question.

ici je choisi mon épaisseur et ensuite de clique sur chaque ligne pour modifier l'épaisseur.

Si je dois choisir une autre épaisseur je dois quitter la routine et la relancer pour une nouvelle épaisseur.

Est-il possible si on termine l'action de revenir sur le menu de choix des épaisseur.

Posté(e)

Personnellement ça ne me dérange pas de relancer le programme pour une nouvelle épaisseur.

Pour répondre à la dernier question, à quel moment (et comment) tu termines l'action ?
A partir de là, tu vas te lancer dans une boucle complexe dont il faudra prévoir une porte de sortie.

Comme déjà dit, il vaut mieux 3 petits programmes tout simple qui font une tâche plutôt qu'un seul qui imbrique tout avec potentiellement des problèmes.

  • Like 1
Posté(e)
il y a 24 minutes, JPhil a dit :

Personnellement ça ne me dérange pas de relancer le programme pour une nouvelle épaisseur.

Pour répondre à la dernier question, à quel moment (et comment) tu termines l'action ?
A partir de là, tu vas te lancer dans une boucle complexe dont il faudra prévoir une porte de sortie.

Comme déjà dit, il vaut mieux 3 petits programmes tout simple qui font une tâche plutôt qu'un seul qui imbrique tout avec potentiellement des problèmes.

@JPhil

Oui je crois que je vais resté sur plusieurs petits programmes.

Par contre est-il possible si on clique dans le vide de ne pas sortir du programme ?

Merci

Posté(e)

Tu peux, mais à un moment donné il faudra bien sortir du programme, donc qu'as-tu prévu comme porte de sortie ? La touche "Echap", la combinaison "Ctrl+C" ou autre ?

Posté(e)

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

Posté(e)

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

Posté(e)

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

Posté(e)

@Luna

Pour le fun j'ai ajouté le changement de couleur

(cons "cOuleur" (list 'color (list 5 "1 2 3 4 5 6 7") (list 'getreal)))

J'ai encore quelques questions :

Quand tu mets list 5 ou list 7 est-ce l'équivalent de initget 5 ?

Est-il possible dans la liste de choix, par exemple pour les couleurs d'afficher en plus du numéro de la couleur avoir le fond qui correspond a la couleur ou juste un texte exemple 1 (Rouge) ?

Merci

Posté(e)

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")

 

il y a 19 minutes, Netparty a dit :

Est-il possible dans la liste de choix, par exemple pour les couleurs d'afficher en plus du numéro de la couleur avoir le fond qui correspond a la couleur ou juste un texte exemple 1 (Rouge) ?

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 :

Citation

Spécifiez la nouvelle valeur de la propriété [1 2 3 4 5 6 7] :

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 !
image.thumb.png.0817888c7fadab2da2be198275dc6c24.png

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

Posté(e)

Ça devient compliqué ton premier lisp. Est-ce un lisp pour la production (là vu le chemin pris je ne pense pas) ou pour le fun de voir ce qu'on peut faire avec du lisp (ça donne l'impression que c'est le chemin pris) ?

Pour la couleur, pourquoi ne pas faire appel à la palette de couleur d'AutoCAD ?

Encore une fois, il faut faire simple, mais surtout se mettre dans la peau d'un utilisateur lambda qui n'a pas envie d'avoir un menu avec 10000 choix.

Si je prends le cas de ton lisp pour l'épaisseur de ligne, perso en tant qu'utilisateur lambda je ne l'utilise pas. En tant qu'utilisateur je m'attends à avoir la question "quelle épaisseur ?" (ou "quelle épaisseur [DuCalque] ?") avec une donnée que je rentre à la main ou "DuCalque" si je tape directement sur la touche "entrée" sans taper le mot "DuCalque". Pour la valeur donnée par l'utilisateur je m'adapte par rapport aux contraintes d'AutoCAD, mais ça reste transparent pour l'utilisateur.

 

Posté(e)

@Luna@JPhil

Merci à vous 2 pour votre aide et votre patience.

Désolé de vouloir aller trop vite, je me suis vite emballé promis je vais prendre le temps de lire plus en profondeur les sujets que vous m'avez proposé.

Passez de bonne fêtes de fin d'année

 

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité