Aller au contenu

[Résolu] Selection d'une polyligne fermée.


stugeol

Messages recommandés

Bonjour,

voici mon but :

 

1) selectionner un objet

2)l'objet est une polyligne?

2.1) non afficher "l'objet selectionné n'est pas une polyligne" puis retour à 1

2.2) oui allez à 3

3) La polyligne st-elle fermée?

3.1) non afficher "l'objet selectionné n'est pas une polyligne fermée" puis retour à 1

3.2) oui fin de la fonction

 

voici la fonction :

(defun c:selectCont ()<;;; Initialisation
(vl-load-com)
(Setq ObjecName Nil)
(setq ObjectClosed :Vlax-False)
 (setq cont nil)<BR>;;; tant que l'objet n'est pas une polyligne fermée<BR>  (While (and (/= ObjectName "AcDbPolyline")
         (/= objectClosed :vlax-true)
    )    ;;selection de l'objet
   (Setq  cont (vlax-ename->vla-object
        (car (entsel "\nSélectionnez une polyligne fermée :"))
      )
   )
   ;;Récupération du nom de l'objet
   (setq ObjecName (vlax-get-property cont 'objectname))
   ;; Si nom de l'objet différent de AcDbPolyline
   (if    (/= ObjectName AcDbPolyline)
     (princ "\nL'objet sélectionné n'est pas une polyligne!")
   )                    ; fin de la boucle if
   ;;Sile nom de l'objet est AcDbPolyline<BR>    (if    (= ObjectName "AcDbPolyline")
     ;;Récupération de la propriété closed
     (setq objectClosed (vlax-get-property cont 'closed))
  )                    ; fin de if
   ;; si Closed est différent de true
  (if    (/= ObjectClosed :vlax-true)
     (Princ "\n l'object sélectionné est une polyligne ouverte")
  ) ;_ fin de if
 ) ;_ fin de while
) ;_ fin de fun

 

Peut importe l'objet seléctionné le message retourné est :L'objet sélectionné n'est pas une polyligne!

puis Sélectionnez une polyligne fermée :

Je ne sort pas de la boucle while.

Où sont les bugs, et quels sont les solutions pour les résoudre?

 

Je vous remercie par avance de votre aide.

cordialement.

Petit à petit on devient moins petit

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

L'erreur est ici :

(if (/= ObjectName AcDbPolyline)

tu compares une chaîne (ObjectName ) avec un symbole non assigné (AcDbPolyline).

Il faut écrire, comme tu le fais plus bas :

(if (/= ObjectName "AcDbPolyline")

 

À part ça, tu devrais déclarer localement tes variables, ça t'éviterait d'avoir à les initialiser à nil.

Ton algorithme est une imbrication de conditions, en le traduisant de manière linéaire comme tu le fais : si l'objet sélectionné n'est pas une polyligne, les autres conditions seront quand même évaluées.

 

Une proposition avec une fonction (pas une commande) qui retourne l'objet polyligne.

 

(defun c:selectCont (/ loop pline)
 (vl-load-com)
 (setq loop T)
 (while loop
   ;; si un objet est sélectionné
   (if
     (and
(setq pline (car (entsel "\nSélectionnez une polyligne fermée: ")))
(setq pline (vlax-ename->vla-object pline))
     )
      ;; si l'objet est une polyligne
      (if (= (vla-get-ObjectName pline) "AcDbPolyline")
 ;; si la polyligne est fermée
 (if (= :vlax-true (vla-get-Closed pline))
   (setq loop nil)		; sortie de la boucle
   (princ "\n l'object sélectionné est une polyligne ouverte")
 )
 (princ "\nL'objet sélectionné n'est pas une polyligne !")
      )
      (princ "\nAucun objet sélectionné !")
   )
 )
 pline
)

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

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Tu peux aussi faire une sélection filtrée sur le bit 70 des polylignes, cela te dispense de faire des tests de validité dans ton code.

 

Exemple de sélection sur des polylignes anciennes (poly3D inclu) et nouvelles, excluant celle qui sont ouvertes et les polymailles

 

(while
 (not
   (setq js
     (ssget "_+.:E:S"
       (list
         (cons 0 "*POLYLINE")
         (cons 67 (if (eq (getvar "CVPORT") 2) 0 1))
         (cons 410 (if (eq (getvar "CVPORT") 2) "Model" (getvar "CTAB")))
         (cons -4 "<AND")
           (cons -4 "<NOT")
             (cons -4 "&") (cons 70 112)
           (cons -4 "NOT>")
           (cons -4 "&") (cons 70 1)
         (cons -4 "AND>")
       )
     )
   )
 )
 (princ "\nPas d'objets valable ou sélection vide!")
)

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

Bonjour,

 

Un peu dans le même esprit que bonuscad qui a été plus rapide, voici une version moins aboutie (qui ne traite que les polylignes optimisée), mais peut-être un peu plus simple à comprendre si on ne maîtrise pas bien les filtres de sélection.

;; Sélectionne une polyligne fermée et renvoie son nom d'entité
(defun c:selectCont (/ sel loop)
 (while (not loop)
   (if
     (and (setq sel (entsel "\nSélectionnez une polyligne fermée: "))
   (ssget (cadr sel) '((0 . "LWPOLYLINE") (70 . 1)))
     )
      (setq loop (car sel))
      (princ "\nSélection non valide !!!")
   )
 )
)

 

Et une variante reprenant ton énoncé de départ :

;; Sélectionne une polyligne fermée et renvoie son nom d'entité
(defun c:selectCont (/ sel loop)
 (while (not loop)
   (cond
     ((not (setq sel (entsel "\nSélectionnez une polyligne fermée: ")))
      (princ "\n Aucun objet sélectionné !")
     )
     ((ssget (cadr sel) '((0 . "LWPOLYLINE") (70 . 0)))
      (princ "\n L'object sélectionné est une polyligne ouverte")
     )
     ((ssget (cadr sel) '((0 . "LWPOLYLINE") (70 . 1)))
      (setq loop (car sel))		; renvoi le nom de la polyligne fermée 
     )					
     (T (princ "\n L'object sélectionné n'est pas une polyligne"))
   )
 )
)

 

A+

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

Merci pour vos solutions.

Je débute en Lisp, je codais avant en VBA .

Ce matin dans le train j'ai réecrit mon code et j'arrive à une solution comparable à celle de gile aux noms de variables prés.

Cependant une question dans les fonctions :

-vla-get-ObjectName

-vla-get-closed

Je peut remplacer le dernier terme (ObjectName, Closed) par n'importe quel propriété de l'objet? Par exemple pour un cercle je peut utiliser vla-get-radius pour récupérer le rayon?

Pour ce qui est des séléctions filtrées j'étudirais le code plus tard au cours de mon évolution, quand je serais capable de me passer des fonctions VLxxxxxx

Encore merci

Petit à petit on devient moins petit

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

Merci pour vos solutions.

 

Une petite dernière plus conforme à ton énoncé de départ et sans employer les filtres de sélection basé sur la consultation des codes DXF via la fonction assoc.

 

(while
 (not
   (and (setq ent (car (entsel "\nSélectionnez une polyligne fermée: ")))
 (= "LWPOLYLINE" (cdr (assoc 0 (setq ent (entget ent)))))
 (if (= 1 (cdr (assoc 70 ent)))
   (princ "\nL'object sélectionné est une polyligne fermée")
   (princ "\nL'object sélectionné est une polyligne ouverte")
 )
   )
 )
)

 

A+

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

(if (= 1 (cdr (assoc 70 ent)))

 

Hum, vaudrait mieux ne pas se limiter à une égalité mais à une opération boléenne sur le bit...

Si tu as le mode "typeligne gen" sur ta polyligne (70 . 128), si celle ci est fermée (70 . 129), ton égalité va écarter cette polyligne qui correspond pourtant au critère.

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

Si tu as le mode "typeligne gen" sur ta polyligne (70 . 128), si celle ci est fermée (70 . 129), ton égalité va écarter cette polyligne qui correspond pourtant au critère.

 

Bien vu, l'opération boléenne est un bon conseil :) :) :)

 

J’avais effectivement oublié les effets de "typeligne gen" et PLINEGEN sur le code 70.

Code corrigé :

(while
   (not
     (and (setq ent (car (entsel "\nSélectionnez une polyligne fermée: ")))
   (= "LWPOLYLINE" (cdr (assoc 0 (setq ent (entget ent)))))
   (if (= 1 (logand (cdr (assoc 70 ent)) 1))
     (princ "\nL'object sélectionné est une polyligne fermée")
     (princ "\nL'object sélectionné est une polyligne ouverte")
   )
     )
   )
 )

 

A+ et merci

Apprendre => Prendre => Rendre

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é