Aller au contenu

Longueurs cumulées des différents types d'entité linéaire par calque


kant_ein

Messages recommandés

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

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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.00

ou :

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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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

  • Upvote 1

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

: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.

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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

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é