bourinox Posté(e) le 15 novembre 2005 Posté(e) le 15 novembre 2005 Bonjour tout le monde, Voila j'ai un souci avec un programme lisp il se bloque dans certaines circonstance et je n'arrive pas trouvé mon erreur. Si quelqu'un peut m'aider ce serait vraiment gentil. Je vous explique le principe. du programme. J'ai des blocs (A, B, C,..Z) que je dois remplacer par d'autre blocs (A1,B1,C1....,Z1) qui eux n'ont pas forcément le même point d'insertion ni la même echelle et qui n'ont pas le même nom.J'ai donc écrit pour commencer un fichier texte tabulé structuré de la façon suivante: Nom bloc existant (tab) Nom bloc cible (tab) Dx (tab) Dy (Tab) echX (Tab) echY Par exemple: si le bloc" A" qui est un carré a comme point d'insertion 0;0 et come longeur 1 mètre, et que le bloc A1 est un carré avec un point d'insertion 0;1 et qui a comme longeur 2 metre.. A (tab) A1 (tab) 1 (tab) 0 (tab) 0,5 (tab) 0,5 Ensuite j'ai écrit un programme lisp qui en faisant appel à ce fichier txt tabulé remplace tous les bloc( A,B,C,...,Z) par les bloc (A1,B1,C1,....,Z1). le voici:(defun c:chblocs () (setq fic (open "C:/sevres/02_Table sandreauDESMOULINS/tabledefdESMOULIN.txt" "r")) (read-line fic) (setq ligne (read-line fic)) (while (/= ligne nil) ;lecture des paramètres (setq posblc2 (vl-string-position 9 ligne)) (setq posdx (vl-string-position 9 ligne (+ posblc2 1))) (setq posdy (vl-string-position 9 ligne (+ posdx 1))) (setq posechx (vl-string-position 9 ligne (+ posdy 1))) (setq posechy (vl-string-position 9 ligne (+ posechx 1))) (setq nomblc1 (substr ligne 1 posblc2)) (setq nomblc2 (substr ligne (+ posblc2 2) (- posdx posblc2 1))) (setq dx (atof (substr ligne (+ posdx 2) (- posdy posdx 1)))) (setq dy (atof (substr ligne (+ posdy 2) (- posechx posdy 1)))) (setq echx2 (atof (substr ligne (+ posechx 2) (- posechy posechx 1)))) (setq echy2 (atof (substr ligne (+ posechy 2) (- (strlen ligne) posechy 1)))) ;echange du bloc (setq jeusel (ssget "x" (list (cons 0 "INSERT") (cons 2 nomblc1)))) (setq nbobj (sslength jeusel)) (setq i 1) (setq listobj (list (ssname jeusel 0))) (repeat (- nbobj 1) (setq listobj (append listobj (list (ssname jeusel i)))) (setq i (+ i 1)) ) (setq i 0) (repeat nbobj (setq objet (nth i listobj)) (setq i (+ i 1)) (setq dxf (entget objet)) (foreach code dxf (progn (if (= (car code) 0) (setq tipe code) ) (if (= (car code) 2) (setq nom code) ) (if (= (car code) 10) (setq coordblc1 code) ) (if (= (car code) 50) (setq rotblc1 (cdr code)) ) (if (= (car code) 41) (setq echxblc1 code) (setq echx (cdr echxblc1)) ) (if (= (car code) 42) (setq echyblc1 code) (setq echy (cdr echyblc1)) ) ) ) (if (= (cdr tipe) "INSERT") (if (= (cdr nom) nomblc1) (progn ;calcul du point d'insertion du nouveau bloc (setq xblc1 (nth 1 coordblc1)) (setq yblc1 (nth 2 coordblc1)) (if (/= dy 0) (progn (setq deca (sqrt (+ (* dx dx echx echx echx2 echx2) (* dy dy echy echy echy2 echy2)))) (setq ang (atan (/ (* dx echx) (* dy echy)))) (setq dx2 (* deca (sin (- ang rotblc1)))) (setq dy2 (* deca (cos (- ang rotblc1)))) (if (< dy 0) (progn (setq dx2 (- 0 dx2)) (setq dy2 (- 0 dy2)) ) ) ) (progn (if (/= dx 0) (progn (if (< dx 0) (setq ang PI) (setq ang 0)) (setq dx2 (* echx2 echx dx (cos (- ang rotblc1)))) (setq dy2 (* echy2 echy dx (sin (+ ang rotblc1)))) ) (progn (setq dx2 (* echx2 echx dx)) (setq dy2 (* echy2 echy dy)) ) ) ) ) (setq coordblc2 coordblc1) (setq coordblc2 (subst (+ xblc1 dx2) xblc1 coordblc2)) (setq coordblc2 (subst (+ yblc1 dy2) yblc1 coordblc2)) ;echange du bloc (setq nvnom (cons 2 nomblc2)) (setq echxblc2 (cons 41 (* echx2 echx))) (setq echyblc2 (cons 42 (* echy2 echy))) (setq dxf (subst nvnom nom dxf)) (setq dxf (subst coordblc2 coordblc1 dxf)) (setq dxf (subst echxblc2 echxblc1 dxf)) (setq dxf (subst echyblc2 echyblc1 dxf)) (entmod dxf) ) ) ) ) (setq ligne (read-line fic)) ) (close fic)) Le problème est le suivant :Quand le programme ne trouve pas le bloc A sur le dessin il s'arrete et ne passe pas au bloc suivant. Sauriez vous d'où cela vient? Voila désolé pour le post pavé et merci d'avance pour les éventuelle réponse.
Florent_bourg Posté(e) le 15 novembre 2005 Posté(e) le 15 novembre 2005 BonjourQue se passe t il si la ligne "(if (= (cdr nom) nomblc1)" renvoit la réponse NON ? car cette ligne renvoit vers une seule (et grande) boucle avec un "PROGN".Donc il si (if (= (cdr nom) nomblc1) renvoit "NON" ... ca se bloque ??? Je te conseille de ne pas mettre 5 IF en parallèle car le déboguage et difficile.Il faut mieux faire plusieurs petit defun plutot qu'un grand, c'est beaucoup plus simple a déboguer...A bientotFlorent
zebulon_ Posté(e) le 15 novembre 2005 Posté(e) le 15 novembre 2005 (setq jeusel (ssget "x" (list (cons 0 "INSERT") (cons 2 nomblc1))))(setq nbobj (sslength jeusel))(setq i 1)(setq listobj (list (ssname jeusel 0)))(repeat (- nbobj 1)(setq listobj (append listobj (list (ssname jeusel i))))(setq i (+ i 1)))(setq i 0)(repeat nbobj(setq objet (nth i listobj))(setq i (+ i 1)) pourquoi faut-il créer une liste listobj à partir du jeu de sélection et ne pas dépiauter directement le jeu de sélection lui-même ? (setq jeusel (ssget "x" (list (cons 0 "INSERT") (cons 2 nomblc1)))) (if jeusel (progn (setq I 0) (while (< I (sslength jeusel)) (setq E (ssname jeusel I)) (setq A (entget E)) (setq NOMBLOCK (strcase (cdr (assoc 2 A)))) (setq PTINS (cdr (assoc 10 A))) (setq ANGROT (cdr (assoc 50 A))) (setq ECHX (cdr (assoc 41 A))) (setq ECHY (cdr (assoc 42 A))) ... insérer ici le code supplémentaire ... (setq I (+ I 1)) ) ) ) je pense que cela simplifiera grandement le code et te permettra de voir plus clair. (if (= (cdr tipe) "INSERT") Je pense que ce if ne sert à rien puisque tu fais un ssget en filtrant justement les INSERT et que donc cette condition sera toujours vraie. Amicalement Zebulon_ [Edité le 16/11/2005 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)
(gile) Posté(e) le 15 novembre 2005 Posté(e) le 15 novembre 2005 Salut, Quelques remarques juste comme çà, je n'ai pas approfondi. Tu devrais déclarer tes variables locales, elle seraient renvoyées à nil à la fin de l'exécution de ta routine, sinon, par exemple, à chaque exécution de la routine, dans la variable listobj vont s'ajouter à la liste précédente, les nouveaux blocs sélectionnés. Tu devrais d'ailleurs essayer de diminuer un peu le nombre de variables. Certaines lignes me semblent inutiles, par exemple :- le premier (read-line fic), - comme le dit zebulon_ , le (if (= (cdr tipe) "INSERT") - mais aussi le (if (= (cdr nom) nomblc1) pour la même raison (ce qui répond à la remarque de Florent_Bourg) Question de style, tu pourrais alléger ton code en supprimant des (progn ... par exemple :(progn (setq dx2 (- 0 dx2)) (setq dy2 (- 0 dy2)) )peu s'écrire :(setq dx2 (- dx2)dy2 (- dy2)) Enfin peu-être ajouter après le (entmod dxf) un (entupd obj). En espérant t'avoir un peu aidé... À plus Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 16 novembre 2005 Posté(e) le 16 novembre 2005 Re, Je n'ai pas essayé ton LISP, mais après avoir laissé décanter un peu. Quand le programme ne trouve pas le bloc A sur le dessin Ton problème me semble venir de la liste listobj qui contiendrait des objets qui ne sont pas sur le dessin, et ce, parcequ'elle n'a pas été "vidée".Quand on utilise une liste affectée à une variable, il est prudent de "vider" la variable avant de la redéfinir avec un (setq listobj nil) au cas où cette variable ait déjà été utilisée dans l'exécution d'un LISP dans lequel elle n'était pas déclarée (d'où l'intérêt de déclarer les variables). Mais dans le cas présent, comme le dit Zebulon_, cette liste n'est pas utile, tu peux parcourir directement le jeu de sélection qui, lui, ne peut contenir que les objets existants dans le dessin et qui sont passé par ton filtre de sélection. Bon courage Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bourinox Posté(e) le 16 novembre 2005 Auteur Posté(e) le 16 novembre 2005 Alors d'abord merci pour votre aide je reprend le programme en essaynt de virer les if mais je l'aime bien cette fonction moi. je testerai ca demain car la j'ai carément planté le truc je sens que je vais m'en arracher des cheveux sur ce truc là
zebulon_ Posté(e) le 16 novembre 2005 Posté(e) le 16 novembre 2005 ...virer les if mais je l'aime bien cette fonction moi Essaie aussi la fonction cond, on s'embête moins avec les progn. (que j'ai justement oublié de mettre dans mon exemple ci dessus :red: ) Un exemple piqué dans l'aide d'autocad (cond ((= what_next 4) ;Prompt user to (getpoint "\npick a point") ;pick pt. ) ((= what_next 0) (prompt "\nuser cancelled dialog") ) ) Si tu aimes les if, tu adoreras les cond Amicalement Zebulon_ [Edité le 16/11/2005 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)
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