kant_ein Posté(e) le 24 janvier 2018 Posté(e) le 24 janvier 2018 Bonjour, Comme indiqué dans le titre, je cherche à obtenir les longueurs cumulées des différents types d'entité linéaire par calque. J'ai trouvé un lisp proposé par (gile) dans ce topic et j'ai tenté de le modifier pour obtenir ce que je veux mais je bloque sur 2 points (guère surprenant vu mon niveau en lisp...). Je souhaiterais que le lisp me donne les longueurs pour les LINE, POLYLINE et LWPOLYLINE. J'ai donc bêtement copier/coller tout le bloc if en changeant le type d'entité. Le décompte d'entités fonctionne mais les longueurs se cumulent lors du passage au type d'entité suivant. En gros, si dans un calque la longueur cumulée de LINE est égale à 2 et la longueur cumulée de LWPOLYLINE est égale à 5, le lisp me sort bien 2 pour les LINE mais 7 pour les LWPOLYLINE. Je ne sais ni quelle variable remettre à 0 ni comment... Je souhaiterais également que les résultats soient triés en suivant l'ordre alphabétique des calques. J'ai essayé de bidouiller avec un vl-sort mais lisp et bidouille ne vont pas bien ensemble ! D'avance un grand merci à celles et ceux qui se pencheront sur mon problème. Demande subsidiaire : si les résultats pouvaient en plus être enregistrés dans un fichier txt au nom du dwg et dans le même répertoire que celui-ci, ce serait Noël le 25 de chaque mois ! Voici le code en question : (defun C:xL_by_layer (/ ss tot nb n long obj lst lay l_lay) (vl-load-com) (if (setq ss (ssget "_X" '((0 . "LINE")))) (progn (setq nb (sslength ss) n 0 tot 0.0) (princ (strcat "\n\nLe dessin contient : " (itoa nb) " LINE") ) (repeat nb (setq obj (vlax-ename->vla-object (ssname ss n)) long (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) tot (+ tot long) lay (vla-get-Layer obj) ) (strcat "\nP" (itoa (setq n (1+ n))) " = " (rtos long) "\tCalque : " lay ) (if (setq l_lay (assoc lay lst)) (setq lst (subst (cons lay (+ long (cdr l_lay))) l_lay lst)) (setq lst (cons (cons lay long) lst)) ) ) (mapcar '(lambda (x) (princ (strcat "\n" (car x) "\t" (rtos (cdr x)) ) ) ) lst ) (princ (strcat "\nLongueur totale dans le dessin = " (rtos tot))) (textscr) ) (princ "\n\nLe dessin ne contient pas de LINE.") ) (if (setq ss (ssget "_X" '((0 . "POLYLINE")))) (progn (setq nb (sslength ss) n 0 tot 0.0) (princ (strcat "\n\nLe dessin contient : " (itoa nb) " POLYLINE") ) (repeat nb (setq obj (vlax-ename->vla-object (ssname ss n)) long (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) tot (+ tot long) lay (vla-get-Layer obj) ) (strcat "\nP" (itoa (setq n (1+ n))) " = " (rtos long) "\tCalque : " lay ) (if (setq l_lay (assoc lay lst)) (setq lst (subst (cons lay (+ long (cdr l_lay))) l_lay lst)) (setq lst (cons (cons lay long) lst)) ) ) (mapcar '(lambda (x) (princ (strcat "\n" (car x) "\t" (rtos (cdr x)) ) ) ) lst ) (princ (strcat "\nLongueur totale dans le dessin = " (rtos tot))) (textscr) ) (princ "\n\nLe dessin ne contient pas de POLYLINE.") ) (if (setq ss (ssget "_X" '((0 . "LWPOLYLINE")))) (progn (setq nb (sslength ss) n 0 tot 0.0) (princ (strcat "\n\nLe dessin contient : " (itoa nb) " LWPOLYLINE") ) (repeat nb (setq obj (vlax-ename->vla-object (ssname ss n)) long (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) tot (+ tot long) lay (vla-get-Layer obj) ) (strcat "\nP" (itoa (setq n (1+ n))) " = " (rtos long) "\tCalque : " lay ) (if (setq l_lay (assoc lay lst)) (setq lst (subst (cons lay (+ long (cdr l_lay))) l_lay lst)) (setq lst (cons (cons lay long) lst)) ) ) (mapcar '(lambda (x) (princ (strcat "\n" (car x) "\t" (rtos (cdr x)) ) ) ) lst ) (princ (strcat "\nLongueur totale dans le dessin = " (rtos tot))) (textscr) ) (princ "\n\nLe dessin ne contient pas de LWPOLYLINE.") ) (princ) )
(gile) Posté(e) le 24 janvier 2018 Posté(e) le 24 janvier 2018 Salut, Donne plutôt un exemple simple mais significatif du résultat souhaité, parce que les modifications apportées à la routine ne permettent pas de le comprendre. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
kant_ein Posté(e) le 24 janvier 2018 Auteur Posté(e) le 24 janvier 2018 Je souhaiterais obtenir quelque-chose comme ça : Le dessin contient : 3 LINE layer_a 10.00 layer_b 5.00 layer_c 3.00 Longueur totale dans le dessin = 18.00 Le dessin ne contient pas de POLYLINE. Le dessin contient : 3 LWPOLYLINE layer_a 8.00 layer_b 6.00 layer_c 9.00 Longueur totale dans le dessin = 23.00 Pour le moment, les longueurs obtenues par layer pour les LWPOLYLINE correspondent au cumul des longueurs de LINE et LWPOLYLINE alors que la longueur totale est bonne : Le dessin contient : 3 LINE layer_a 10 layer_b 5 layer_c 3 Longueur totale dans le dessin = 18 Le dessin ne contient pas de POLYLINE. Le dessin contient : 3 LWPOLYLINE layer_a 18 layer_b 11 layer_c 12 Longueur totale dans le dessin = 23 Merci de ton intérêt pour mon problème.
(gile) Posté(e) le 24 janvier 2018 Posté(e) le 24 janvier 2018 S'il y a 3 lignes dont 2 sur le calque layer_a, faut-il écrire :Le dessin contient : 3 LINE layer_a 10.00 layer_a 5.00 layer_c 3.00 Longueur totale dans le dessin = 18.00ou :Le dessin contient : 3 LINE layer_a 15.00 layer_c 3.00 Longueur totale dans le dessin = 18.00 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
kant_ein Posté(e) le 24 janvier 2018 Auteur Posté(e) le 24 janvier 2018 La 2ème proposition (cumul de la longueur des entités par calque).L'intérêt de cette routine pour moi est d'évaluer rapidement le linéaire des différents réseaux dans un fichier de récolement (malheureusement pas forcément conforme au gabarit défini par notre structure).
kant_ein Posté(e) le 24 janvier 2018 Auteur Posté(e) le 24 janvier 2018 Je m'aperçois que dans mon exemple les calques sont sortis dans l'ordre alphabétique. Un hasard ? Ils n'ont pas été créés dans cet ordre. [Edit] Un coup du hasard ! Un nouveau test m'a donné ça :Le dessin contient : 6 LWPOLYLINE beta 12 alpha 8 delta 11 layer_a 18 layer_b 11 layer_c 12 Longueur totale dans le dessin = 54
(gile) Posté(e) le 24 janvier 2018 Posté(e) le 24 janvier 2018 (defun C:xL_by_layer (/ ss lines plines 2dplines 3dplines objName layer leng lst sum str ) (vl-load-com) ;; sélection de toutes les lignes et polylignes (tous types) (if (ssget "_X" '((0 . "LINE,*POLYLINE"))) (progn (vlax-for obj (setq ss (vla-get-ActiveSelectionSet (vla-get-Activedocument (vlax-get-acad-object) ) ) ) (setq objName (vla-get-ObjectName obj) layer (vla-get-Layer obj) leng (vla-get-Length obj) ) ;; construction d'une liste pour chaque type d'entité (cond ((= objName "AcDbLine") (setq lines (cons (cons layer leng) lines)) ) ((= objName "AcDbPolyline") (setq plines (cons (cons layer leng) plines)) ) ((= objName "AcDb2dPolyline") (setq 2dplines (cons (cons layer leng) 2dplines)) ) ((= objName "AcDb3dPolyline") (setq 3dplines (cons (cons layer leng) 3dplines)) ) ) ) (vla-Delete ss) ;; contruction d'une chaîne de caractère (setq str "") ;; traitement par liste (mapcar (function (lambda (l n) (if l (progn ;; nombre d'entité dans la liste (setq str (strcat str "Le dessin contient : " (itoa (length l)) " " n (if (= 1 (length l)) "\n" "s\n" ) ) ) ;; somme des longueurs par calque (setq lst nil) (foreach p l (setq lst (if (setq sum (assoc (car p) lst)) (subst (cons (car p) (+ (cdr p) (cdr sum))) sum lst) (cons p lst) ) ) ) (foreach p (vl-sort lst (function (lambda (a B) (< (car a) (car B))))) (setq str (strcat str (car p) " " (rtos (cdr p)) "\n" ) ) ) ;; somme des longueur pour le type d'entité (setq str (strcat str "Longueur totale dans le dessin = " (rtos (apply '+ (mapcar 'cdr l))) "\n\n" ) ) ) ;; pas d'entité de ce type (setq str (strcat str "Le dessin ne contient pas de " n "\n\n" ) ) ) ) ) (list lines plines 2dplines 3dplines) '("Ligne" "Polyligne" "Polyligne 2d" "Polyligne 3d") ) (terpri) ;; écriture des résultats dans la fenêtre de texte (prompt str) ;; écriture des résultats dans un fichier texte (setq file (open (strcat (getvar 'dwgprefix) (vl-filename-base (getvar 'dwgname)) ".txt") "w") ) (princ str file) (close file) ) ) (princ) ) 1 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
kant_ein Posté(e) le 24 janvier 2018 Auteur Posté(e) le 24 janvier 2018 :blink: Je savais en postant ici que j'aurais de l'aide. De là à imaginer un lisp tout neuf entièrement réalisé suivant mes contraintes et en moins d'une demie journée... Gilles, un immense merci ! Je ne pourrais tester ça que demain mais je ne doute pas un instant que ça fasse le job.
kant_ein Posté(e) le 25 janvier 2018 Auteur Posté(e) le 25 janvier 2018 Bonjour, Après avoir testé sur 2 fichiers différents, le résultat du lisp est concis... Le dessin ne contient pas de Polyligne 3d Le lisp fait sans doute le job mais le résultat affiché (prompt et txt) concerne uniquement le dernier type d'entité linéaire traité. On dirait que les instructions d'écriture des résultats n'interviennent qu'à la toute fin du lisp au lieu d'intervenir à chaque itération de type d'entité linéaire (du moins c'est comme ça que j'interprète le problème avec ma vision plus Python que Lisp).
(gile) Posté(e) le 25 janvier 2018 Posté(e) le 25 janvier 2018 C'est une erreur de ma part.Le LISP construit une chaine de caractères en concaténant (srtcat) les résultats pour les différents types d'entité.J'avais oublié la variable str (la chaine en construction) dans l'expression (strcat ...) du cas où il n'y a pas d'entité de ce type. Comme les polylignes 3d sont traitées en dernier, la chaine "Le dessin ne contient pas de Polyligne 3d" a écrasé tout ce qui avait été construit avant. J'ai corrigé le code ci dessus. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
kant_ein Posté(e) le 25 janvier 2018 Auteur Posté(e) le 25 janvier 2018 Ça fonctionne !!! Et grâce à toi c'est bien parti pour que Noël tombe le 25 de chaque mois cette année ! Mille mercis
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