Aller au contenu

Luna

Membres
  • Compteur de contenus

    1 113
  • Inscription

  • Dernière visite

  • Jours gagnés

    42

Tout ce qui a été posté par Luna

  1. Salut, merci d'avoir été aussi rapide ;) voici ce que j'obtiens avec l'exemple ci-dessus : Commande: (setq lst '("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000")) ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000") Commande: (acad_strlsort lst) ("P_10" "P_1000" "P_8" "P_89" "P_899" "P_9" "P_90" "P_900" "P_91" "P_989" "P_990" "P_991" "P_999") Commande: (setq lst '("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000" "PT_1" "PT_3" "PT44" "PT22" "Ceci" "est" "un" "test")) ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000" "PT_1" "PT_3" "PT44" "PT22" "Ceci" "est" "un" "test") Commande: (acad_strlsort lst) ("Ceci" "est" "P_10" "P_1000" "P_8" "P_89" "P_899" "P_9" "P_90" "P_900" "P_91" "P_989" "P_990" "P_991" "P_999" "PT_1" "PT_3" "PT22" "PT44" "test" "un") Du coup ça ne correspond pas vraiment à mes attentes... mais merci, il est vrai que c'est encore un peu obscur les fonctions acad_*, acet-* et autres car je ne vois pas encore leur différenciation par rapport au LISP vanilla, ActiveX et Visual...^^' Luna
  2. Bonjour à toutes et à tous ! Je n'ai pas su trouver une réponse à mon problème (bon c'est pas vraiment un problème mais plus une question d'esthétique ..) : j'ai remarqué que la fonction (vl-sort) utilisée de manière "basique" donc avec la fonction de comparaison égale à '<, ben les valeurs ne sont pas rangées correctement...ou du moins pas comme on s'attend à ce qu'elles le soient ! Un exemple (parce que c'est plus simple à comprendre ^^) : Commande: (setq lst '("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000")) ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000") Commande: (vl-sort lst '<) ("P_10" "P_1000" "P_8" "P_89" "P_899" "P_9" "P_90" "P_900" "P_91" "P_989" "P_990" "P_991" "P_999") Commande: (vl-sort lst '(lambda (e1 e2) (< e1 e2))) ("P_10" "P_1000" "P_8" "P_89" "P_899" "P_9" "P_90" "P_900" "P_91" "P_989" "P_990" "P_991" "P_999") Ici la liste est simplifiée, c'est-à-dire que la structure des chaînes de caractères est identique (un préfixe "P_" suivi d'un nombre) et on s'attends donc à ce que la fonction (vl-sort) retourne : ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000") Donc pour ce cas "particulier" car il ne peut pas être pris comme une généralité on peut le traiter comme suit : Commande: (vl-sort lst '(lambda (e1 e2) (and (< e1 e2) (< (strlen e1) (strlen e2))))) ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000") On a le résultat escompté, mais je suis pas satisfaite pour autant ... Parce que même si cela peut fonctionner pour un cas particulier, soit, mais je souhaiterais plutôt avoir une fonction qui fonctionne dans tous les cas (de manière générale quoi) ce qui m'éviterai d'avoir à gérer les cas particuliers à chaque fois (ce qui n'est parfois pas possible car on ne connais pas le résultat) Si on change la liste, et que l'on passe sur un cas plus général, ça marche plus (ce qui est évident vu la simplicité de son écriture... : Commande: (setq lst '("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000" "PT_1" "PT_3" "PT44" "PT22" "Ceci" "est" "un" "test")) ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000" "PT_1" "PT_3" "PT44" "PT22" "Ceci" "est" "un" "test") Commande: (vl-sort lst '(lambda (e1 e2) (and (< e1 e2) (< (strlen e1) (strlen e2))))) ("P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "PT_1" "PT_3" "PT44" "PT22" "Ceci" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000" "est" "un" "test") Bref, là pour le coup, c'est l'idée ou plutôt la logique de résolution que je ne trouve pas... Je n'ai pas forcément besoin d'un code complet tout bien fait qui réponde à ma question (ça gâche le plaisir parfois ^^), se serait plutôt des pistes de recherches sur la logique... Je pars sur l'hypothèse, que je ne sais rien de la liste retournée/étudiée, donc dans l'idée il faut je pense se baser sur le tri de chaînes de caractères (via la fonction (vl-princ-to-string) pour s'assurer que l'on compare pas un œuf avec une poule) et effectuer un premier tri "grossier" qui consiste à les trier dans l'ordre alphabétique puis identifier la succession de chaînes identiques mais incrémentées pour les trier au sein de ces "successions" dans l'ordre des incrémentations. Pour au final obtenir (si on conserve notre dernier exemple) : ("Ceci" "PT22" "PT44" "PT_1" "PT_3" "P_8" "P_9" "P_10" "P_89" "P_90" "P_91" "P_899" "P_900" "P_990" "P_989" "P_991" "P_999" "P_1000" "est" "test" "un") Du coup je me pose la question du fonctionnement interne de la fonction (vl-sort), car si je comprend bien son fonctionnement logique sur une chaîne de caractères, elle compare les valeurs ASCII (un peu comme (vl-string->list) qui retourne la liste des codes ASCII de chaque caractères de la chaîne) pour les trier selon ces valeurs (et ainsi trier des nombres, ce qui est la seule..."possibilité" du point de vue informatique).. Donc je suppose que pour pouvoir faire cette fonction générale, je dois me rapprocher du fonctionnement natif de la fonction pour trier mes valeurs d'après leur équivalence en liste ASCII auxquel cas... une fonction récursive ? (je n'ai jamais mis les pattes encore dans ce domaine alors pardon si je dis des bêtises --') Et ainsi trier la liste entrée en argument selon son premier code ASCII, retourne la liste, trie d'après le second code ASCII, retourne la liste, trie selon le troisième, etc Mais du coup..On se retrouve finalement à devoir gérer les écarts de longueurs de string (strlen) différents et qui font "disparaître" les chaînes de la liste donc potentiellement qu'il faudrait équilibrer les longueurs de liste en ajoutant un caractère nul (ascii "") -> 0, mais du coup, conserver la liste originelle pour éviter de renvoyer des erreurs ? Et une telle méthode risque d'être....longue, voire très longue car si j'ai une liste contenant 5 000 valeurs et chaque valeur à une longueur de 30 caractères, bah ça va pas trier de manière instantanée.. Bref, je suis un peu perdue dans mes réflexions et un peu d'aide pour y voir plus clair me ferait grand plaisir ! Merci, Luna
  3. Luna

    Lisp Select-filter

    Bonjour à toutes et à tous, Après beaucoup de travail acharné, je me suis dit que je pourrais partager une routine que j'utilise au quotidien sur autoCAD et aussi dans mes programmes : (select-filter). Le but est assez simple, elle retourne un jeu de sélection (au même titre que la fonction (ssget) en appliquant des filtres) ainsi que le détail du nombre d'objets sélectionnés en fonction des différentes méthodes programmées. C'est encore un peu brouillon et c'est loin d'être aussi parfait et optimisé que des routines de (gile) ou Patrick_35 (et je serais ravie d'avoir des propositions d'amélioration), mais je n'ai pas encore eu de problèmes alors.. ^^" Je post le fichier .lsp correspondant (ça risque d'être un peu trop long si je le poste en dur ^^') 2020-03-17_Select-filter.LSP Bref voilà, si jamais ça aide certaines personnes j'en serai ravie, et si j'ai des retours et/ propositions d'amélioration, je suis preneuse également ! ;) Et puis il y a également quelques fonctions nécessaires à son fonctionnement qui peuvent également s'avérer utiles (Je remercie d'ailleurs Lee-Mac pour ses fonctions sur les blocs dynamiques et sur les options de la fonction (ssget) !!) Bisous !
  4. Merci pour ta réponse, je n'avais pas vu que Lee Mac avait fait une page spécialement pour la fonction (ssget) ! --' En revanche, si je comprend bien, le "+." ne sert pas de "liaison" entre les différents mode de sélection mais uniquement à forcer la sélection pour les entités situées sous le curseur (un peu équivalent à la méthode "_:E"). Mais du coup, si je cherche à utiliser la méthode "I" (Implied) combinée à la méthode "CP" (Capture Polygon), cette écriture ne fonctionne pas ... : (setq jsel (ssget "_:I:CP" [pt-list])) cela provient sûrement du fait que les méthodes Implied et Capture Polygon ne possède pas de ":" lors de leur utilisation... Ahhhh (pardon..) à priori, en suivant cette logique : (setq jsel (ssget "_ICP" [pt-list])) Me retourne bel et bien un jeu de sélection, mais il ne s'agit pas de l'intersection entre la méthode "I" et la méthode "CP"... (je sais pas si je suis très claire là..) --" en faisant quelques test, la fonction (ssget) ne lis pas la totalité de la chaîne, elle s'arrête à la première méthode connue et l'applique, en gros : (setq jsel (ssget "_ICP" [pt-list])) est strictement équivalent à (setq jsel (ssget "_I")) et différent de (setq jsel (ssget "_CPI" [pt-list])) qui est strictement équivalent à (setq jsel (ssget "_CP" [pt-list])) Donc je reviens à la case départ... il n'existe pas de manière de combiner les méthodes qui ne possèdent pas ":" ? Car en comparaison (et en lien aux messages précédant), on a bien : (setq jsel (ssget "_:E")) différent de (setq jsel (ssget "_:S:E")) Donc ici, les deux méthodes se combinent... Raaahhh...c'est rageant !! :angry: Bon merci pour ta réponse encore ! :)
  5. Salut, je me permet de répondre à ce sujet car j'ai quelques questions vis-à-vis des additions d'options de la fonction (ssget)... J'ai trouvé la méthode pour ne sélectionner qu'un unique objet situé au-dessous du curseur avec : (ssget "_:S+.") Cependant, je n'arrive pas à trouver d'aide/forum qui parle d'une méthode pour effectuer plusieurs méthodes sur un seul (ssget).. Mon idée serait de prendre en compte la pré-sélection lors du lancement de ma fonction, donc pour ça, j'ai accès à ce jeu de sélection (nommé "jsel") grâce aux méthodes : (setq jsel (last (ssgetfirst))) ;; ou bien (setq jsel (ssget "I")) Sachant que la seconde méthode permet d'ajouter un filtre à la sélection si nécessaire (donc c'est celle que j'utilise) Mais comment faire pour ne conserver les objets pré-sélectionnés qui appartiennent à une zone définie par une liste de points ? (setq jsel2 (ssget "CP" (pt-list))) L'idée étant de combiner les deux pour m'éviter d'avoir à parcourir le premier jeu "jsel" via une boucle (while) ou un (repeat) pour en supprimer les objets qui n'appartiennent pas au jeu de sélection "jsel1" via (ssmemb) et (ssdel).. Sauf que, impossible de trouver une syntaxe correcte du genre : (setq jsel (ssget "I+CP")) ;; ou bien (setq jsel (ssget "_I+_CP")) Bref... je suis perdue.. donc si jamais vous avez une solution, je suis preneuse ! Merci !! ;)
  6. Sumimasen (gile), tes explications resteront toujours un exemple de perfection ! :) @David64, pour ce qui est de la fonction (atof) tu peux essayer de voir directement via l'aide d'autocad. Mais pour résumer, la fonction (atof) est l'inverse de la fonction (rtos). Donc en clair, cela permet de passer une chaîne de caractères de la forme "3.14" en un nombre réel 3.14 peut ainsi s'avérer très utile lors de l'utilisation de la fonction (/) puisque le résultat n'est pas le même si le dénominateur est un réel ou un entier ^^ (/ 5 2) -> 2 (/ 5 2.0) -> 2.5 si j'ai bien compris son utilisation, la fonction (/) renvoie toujours le résultat au même format que le dénominateur donc il arrive parfois que l'on soit obligé de passer par (/ 5 (atof (rtos 2 2 1))) -> 2.5 (et non 2) Bref. pour le code, je pense que ceci devrait fonctionner (non testé) : ;;;Test Insérer DXF (defun c:test (/ echelle) ;;Définit la valeur des unités de contenu sources en cm (setvar "INSUNITSDEFSOURCE" 5) ;;Définit la valeur des unités de dessin cible en m (setvar "INSUNITSDEFTARGET" 6) (command (getcname "ECHLTP") 7 (getcname "inserclassique") (getcname "decompos") (ssget "_A") (getcname "-purger") "ca" "" "n" (getcname "-epurer") (ssget "_A") "" "Terminé" (initdia) (getcname "sauvenom")) (setvar "INSUNITSDEFSOURCE" 0) (alert "Sélectionner la(es) coupe(s)") ;; un (prompt) pourrait également faire l'affaire, en fonction de l'utilisation :) (progn (initget 1 "5 10 15 20 25 33 40 50 75 100") (if (= "33" (setq Echelle (getkword "\nChoisissez l'échelle [5/10/15/20/25/33/40/50/75/100]:"))) (setq Echelle 0.033333) (setq Echelle (/ 1 (atof Echelle))) ) ) (command (getcname "_scale") (ssget) "" "0,0.18587899" Echelle) (command (getcname "_scale") (ssget "_W" '(1.3 1.3) '(-0.5 -0.5)) "" "0,0" Echelle) (princ) ) En prenant en compte ... normalement ^^'L'utilisation du (progn) n'est pas obligatoire, mais j'ai déjà eu quelques soucis de compatibilité entre plusieurs initget d'affilé alors, on n'est jamais trop prudente !! ^^ (voir ce sujet) En espérant que cela fonctionne .. ;)
  7. Salut ! tu peux regarder du côté de (initget) et (getkword). Ces deux fonctions devraient résoudre ton soucis :) initget affectera uniquement la fonction (get-...) qui le suit et (getkword) permet d'afficher des "key", des choix prédéfinis dans un message sur la ligne de commande. donc dans l'idée tu aurais quelque chose comme ça : (initget 1 "5 10 15 20 25 33.333 40 50 75 100") (setq Echelle (getkword "\nChoisir échelle [5/10/15/20/25/33.333/40/50/75/100] : ")) Si je me souviens bien, il est possible que le 33.333 ne passe pas en raison de la virgule (".") donc à voir... Ici, le 1 spécifié au niveau de (initget) permet d'interdire l'utilisateur de faire une validation à vide (ENTER) ce qui retourne alors nil et peut poser des soucis !! Et surtout, (getkword) retourne une chaîne de caractère donc si jamais tu as besoin de l'échelle sous format numérique il faudra convertir la chaîne via (rtos) ou bien (itoa) :) Voili voilou !!
  8. Pas de soucis, je ne connaissais pas la variable INSUNITSDEFSOURCE, voilà tout ;)
  9. Hey ! Dans un premier temps, je crois que tu as inversé la correspondance entre les unités et la valeur de la variable système ;) (4 = Millimètre et 6 = Mètre) Ensuite je pense que cela devrait suffire à tes besoins : (setvar "MODEMACRO" "$(if,$(eq,$(getvar,INSUNITS),6),Mètre,$(if,$(eq,$(getvar,INSUNITS),4),Millimètre,Non défini))") ça remplace la ligne : (command "modemacro" "Mètre = 4 Millimètre = 6 : $(getvar, insunitsdefsource)") Si l'unité change en cours de route, la variable MODEMACRO se mettra à jour correctement. :) Si l'unité est différente de Mètre ou Millimètre ça affichera "non défini". PS : tu n'es pas obligé de passer par les commandes pour définir les variables systèmes INSUNITS, DIMSCALE, DIMLFAC et MLEADERSCALE. tu peux utiliser les fonctions (setvar), qui n'affiche rien dans l'historique de commande. (defun C:CONVM () (setvar "INSUNITS" 6) (setvar "DIMSCALE" 1000) (setvar "DIMLFAC" 1) (setvar "MLEADERSCALE" 1000) (setvar "MODEMACRO" "$(if,$(eq,$(getvar,INSUNITS),6),Mètre,$(if,$(eq,$(getvar,INSUNITS),4),Millimètre,Non défini))") ) Voili voilou en espérant t'avoir aidé ^^
×
×
  • 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é