Aller au contenu

Récurrences non reconnues (erreur: no function definition: BOUCLE)


Déméter_33

Messages recommandés

Bonjour,

Dans le cadre de l'optimisation d'une routine complexe comprenant un ensemble de fonction diverses, j'essaye d'améliorer les commandes en les testant indépendamment.

Pour optimiser ce fonctionnement, je teste actuellement un morceau de la routine, dans laquelle j'essaye de mettre en place une boucle, qui répète l'ensemble de la fonction de dessin d'une -spline annotée, et ce à l'aide d'un choix oui/non en fin de la fonction principale, qui si "oui" renvoie sur une fonction 'BOUCLE', qui renvoie ensuite sur la fonction de dessin 'FISS'.

Je ne sais pas si mon explication est claire, mais en gros voici ce qui se passe:

Lorsque j'exécute BOUCLE, l'exécution de FISS se déroule parfaitement, jusqu'à la fin, puis lors du choix "oui" (pour répéter l'opération), le message suivant apparait:

erreur: no function definition: BOUCLE

Alors que la première fois, l'exécution s'est très bien passée.

Je ne comprend pas trop pourquoi, et si vous trouvez une aide à m'apporter, j'aimerai si possible l'explication qui va avec ( ;-P) 

Merci d'avance.

PS: pour la bonne exécution de la fonction FISS, le bloc ci-joint "bar" est requis. L'une des autres améliorations prévues est de créer le bloc dans une fonction propre pour rendre la routine autonome.

PPS: Je suis débutant en LISP

Test fissure seule.lsp bar.dwg

Modifié par Déméter_33
Ajout d'une PPS
Lien vers le commentaire
Partager sur d’autres sites

Coucou,

Je pense qu'il y a une erreur de vocabulaire (soit dans ton explication, soit dans ton programme), car tu as

(defun c:BOUCLE()

donc il s'agit d'une commande, et non d'une fonction étant donné que le nom est précédé d'un

c:

Je n'ai pas vraiment lu ton programme dans sa globalité, mais je ne pense pas que l'écriture soit des plus optimisée... La commande BOUCLE exécute ceci :

  (progn
    (while (< (getvar "cmdactive") 0)
          (Command pause)
    )
    (FISS)
    (princ)
  )

mais si l'on regarde la fonction FISS, tu exécutes ceci au niveau de la seule utilisation de (BOUCLE) :

      (progn
        (while (< (getvar "cmdactive") 0)
          (Command pause)
        )
        (BOUCLE)                      ;la commande est renouvelée
        (princ)
      )

Donc je ne comprends pas bien à quoi sert la commande/fonction BOUCLE étant donné que si tu peux sortir du (while) de FISS avant l'exécution de (BOUCLE), alors tu n'entreras même pas dans le (while) situé dans (BOUCLE).... et autrement dit cela reviendrait à juste exécuter (FISS) de nouveau ! Et pour cela rien de plus simple, tu supprimes le (defun c:BOUCLE ...) et tu remplaces le (BOUCLE) par (FISS) dans ta fonction FISS ^^

Je n'ai pas testé mais cela peut être une piste de recherche, car j'ai comme l'impression que tu te compliques un peu trop la vie 😉

Bisous,
Luna

Lien vers le commentaire
Partager sur d’autres sites

il y a 23 minutes, Luna a dit :

Donc je ne comprends pas bien à quoi sert la commande/fonction BOUCLE étant donné que si tu peux sortir du (while) de FISS avant l'exécution de (BOUCLE), alors tu n'entreras même pas dans le (while) situé dans (BOUCLE).... et autrement dit cela reviendrait à juste exécuter (FISS) de nouveau ! Et pour cela rien de plus simple, tu supprimes le (defun c:BOUCLE ...) et tu remplaces le (BOUCLE) par (FISS) dans ta fonction FISS ^^

En effet, je n'avais pas compris qu'on pouvait appeler la commande à l'intérieur d'elle même. Dans ma tête ca me disait "il faut en sortir puis y rerentrer...

Du coup ca marche.

Bon je suis vraiment en dessous du niveau débutant du coup...

il y a 24 minutes, Luna a dit :

Je n'ai pas vraiment lu ton programme dans sa globalité, mais je ne pense pas que l'écriture soit des plus optimisée...

Si jamais tu dédaignes jeter un regard sur le reste de la fonction et que tu as des pistes d'amélioration, je suis preneur à 100%.

Lien vers le commentaire
Partager sur d’autres sites

Bonjour @Déméter_33

Je confirme que l'écriture n'est pas vraiment "optimisée", mais n'en prends pas ombrage.
Je constate que tu fais des efforts en essayant seul d'avancer et ça, ça me plaît.
Sois assuré que nous (les forums) sommes sur ton chemin si tu veux progresser et n'hésite pas à nous questionner.

On sera en mesure de te donner des postes d'amélioration en échangeant avec toi, car on se doute un peu de ce que fait le programme, mais ce serait mieux que tu expliques les buts à atteindre parce qu'en se basant seulement sur ce qu'on interprète du code, on ne sait pas tout et de ce fait pas certain de te trouver la vraie solution.

Amicalement

 

Lien vers le commentaire
Partager sur d’autres sites

Il y a 22 heures, Déméter_33 a dit :

Si jamais tu dédaignes jeter un regard sur le reste de la fonction et que tu as des pistes d'amélioration, je suis preneur à 100%.

Bonjour,

Je te propose une version un peu plus poussée (si j'ai bien compris la boucle que tu voulais faire)

Elle emploi les code DXF (il me semble essentiel qu'un lispeur se familiarise avec ces codes), j'ai évité les fonction (vlax- qui sont plus performantes mais encore plus obscur pour un débutant.

Ce code s'occupe de créer le calque, le style de texte et le bloc s'ils n'existent pas.

Il évite l'emploi de (command "xxx") sauf pour la création de la spline.

Après il y a plein de moyen de faire, j'ai poussé un peu mais pas trop (je suis rester en vanilla lisp qui serait compatible avec des clones d'Autocad)

(defun c:FISS(/ l_var rep dxf_210 pt_ins dxf_ent tmp O)
  (if (not (tblsearch "STYLE" "DIADES"))
    (entmake
      '(
        (0 . "STYLE")
        (100 . "AcDbSymbolTableRecord")
        (100 . "AcDbTextStyleTableRecord")
        (2 . "DIADES")
        (70 . 0)
        (40 . 2.0)
        (41 . 1.0)
        (50 . 0.0)
        (71 . 0)
        (42 . 2.0)
        (3 . "arial.ttf")
        (4 . "")
      )
    )
  )
  (if (not (tblsearch "LAYER" "102-PATHO SECHE"))
    (entmake
      '(
        (0 . "LAYER")
        (100 . "AcDbSymbolTableRecord")
        (100 . "AcDbLayerTableRecord")
        (2 . "102-PATHO SECHE")
        (70 . 0)
        (62 . 1)
        (6 . "Continuous")
        (290 . 1)
        (370 . -3)
      )
    )
  )
  (if (not (tblsearch "BLOCK" "bar"))
    (progn
      (entmake
        '((0 . "BLOCK") (2 . "bar") (70 . 2) (8 . "0") (62 . 0) (6 . "ByBlock") (370 . -2) (10 0.0 0.0 0.0))
      )
      (entmake
        '(
          (0 . "LINE")
          (100 . "AcDbEntity")
          (67 . 0)
          (410 . "Model")
          (8 . "0")
          (62 . 0)
          (6 . "ByBlock")
          (370 . -2)
          (100 . "AcDbLine")
          (10 -1.451108208811707 0.0 0.0)
          (11 1.451108208811707 0.0 0.0)
          (210 0.0 0.0 1.0)
        )
      )
      (entmake '((0 . "ENDBLK") (8 . "0") (62 . 0) (6 . "ByBlock") (370 . -2)))
    )
  )
  (setq
    l_var (mapcar 'getvar '("OSMODE" "AUTOSNAP"))
    rep "Oui"
  )
  (mapcar 'setvar '("OSMODE" "AUTOSNAP") '(512 55))
  (initcommandversion 2)
  (command  "_.spline")
  (while (not (zerop (getvar "CMDACTIVE")))
    (command pause)
  )
  (initcommandversion 1)
  (setq dxf_210 (assoc 210 (entget (entlast))))
  (while (eq rep "Oui")
    (initget 9)
    (setq pt_ins (trans (getpoint "\nDonner la position: ") 1 0))
    (entmake
      (list
        '(0 . "INSERT")
        '(100 . "AcDbEntity")
        '(67 . 0)
        '(410 . "Model")
        '(8 . "102-PATHO SECHE")
        '(100 . "AcDbBlockReference")
        '(2 . "bar")
        (cons 10 (trans pt_ins 0 (cdr dxf_210)))
        '(41 . 1.0)
        '(42 . 1.0)
        '(43 . 1.0)
        '(50 . 0.0)
        '(70 . 0)
        '(71 . 0)
        '(44 . 0.0)
        '(45 . 0.0)
        dxf_210
      )
    )
    (setq dxf_ent (entget (entlast)))
    (princ "\nDonner l'angle du bloc: ")
    (while (= 5 (car (setq tmp (grread t 5 1))))
      (entmod (subst (cons 50 (angle pt_ins (trans (cadr tmp) 1 0))) (assoc 50 dxf_ent) dxf_ent))
      (entupd (cdar dxf_ent))
    )
    (initget 1)
    (setq O (getint "\nDonner la valeur de l'Ouverture O:"))
    (entmake
      (list
        '(0 . "TEXT")
        '(100 . "AcDbEntity")
        '(67 . 0)
        '(410 . "Model")
        (cons 8 (getvar "CLAYER"))
        '(100 . "AcDbText")
        (cons 10 (trans pt_ins 0 (cdr dxf_210)))
        '(40 . 2.0)
        (cons 1 (strcat "O:" (itoa O) "mm"))
        '(50 . 0.0)
        '(41 . 1.0)
        '(51 . 0.0)
        '(7 . "DIADES")
        '(71 . 0)
        '(72 . 0)
        '(11 0.0 0.0 0.0)
        dxf_210
        '(100 . "AcDbText")
        '(73 . 0)
      )
    )
    (setq dxf_ent (entget (entlast)))
    (princ "\nDonner la position du texte: ")
    (while (= 5 (car (setq tmp (grread t 5 1))))
      (entmod (subst (cons 10 (trans (cadr tmp) 1 (cdr dxf_210))) (assoc 10 dxf_ent) dxf_ent))
      (entupd (cdar dxf_ent))
    )
    (initget "Oui Non")
    (setq rep (getkword "\nContinuer ? [Oui/Non] <Oui>: "))
    (if (not (eq rep "Non")) (setq rep "Oui"))
  )
  (mapcar 'setvar '("OSMODE" "AUTOSNAP") l_var)
  (prin1)
)

 

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

Merci @didier, c'est encourageant pour la suite, qui va être longue, car dans le LISP de base, il y a une bonne cinquantaine de sous fonction du même genre que celle vue à réévaluer...

Merci aussi @bonuscad pour ta présentation du code sous une forme que je ne connaissait pas du tout, et sur laquelle je vais un peu plus me renseigner, toutefois, je t'avoue que pour le niveau auquel je code, et surtout pour l'utilisation en sortie (j'optimise une barre "pathologies" qui nous aide à dessiner des désordres sur des structures en génie civil), mais plus important de la base du code que je suis en train de reprendre (de son écriture), je ne me vois pas changer les 2000 et + de lignes en réécrivant celui-ci en totalité, dans une forme dont je ne connais pour le moment que le nom (on parle même pas du vlax).

De plus, l'objectif est d'avoir un code commenté compréhensible par un néophyte (qui sera plus comme moi habitué à appeler des commandes), au cas ou je ne travailles plus dans la boite dans laquelle je suis, pour qu'il puisse comprendre quelle est la méthodologie appliquée sur les éléments automatisés qui nous permettent d'économiser beaucoup de temps.

Le 15/04/2023 à 18:42, bonuscad a dit :
(if (not (tblsearch "BLOCK" "bar"))
    (progn
      (entmake
        '((0 . "BLOCK") (2 . "bar") (70 . 2) (8 . "0") (62 . 0) (6 . "ByBlock") (370 . -2) (10 0.0 0.0 0.0))
      )
      (entmake
        '(
          (0 . "LINE")
          (100 . "AcDbEntity")
          (67 . 0)
          (410 . "Model")
          (8 . "0")
          (62 . 0)
          (6 . "ByBlock")
          (370 . -2)
          (100 . "AcDbLine")
          (10 -1.451108208811707 0.0 0.0)
          (11 1.451108208811707 0.0 0.0)
          (210 0.0 0.0 1.0)
        )
      )
      (entmake '((0 . "ENDBLK") (8 . "0") (62 . 0) (6 . "ByBlock") (370 . -2)))
    )
  )

En revanche, ce que tu lève là m'intéresse au plus haut point, et est un autre sujet sur lequel je me renseigne: la création automatique d'un bloc simple par un lisp.

Mais ca sera surement le sujets d'autres fois.... (voire une autre demande)

En tout cas merci beaucoup pour votre aide.

Lien vers le commentaire
Partager sur d’autres sites

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é