benalto Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 Bonsoir à tous, je cherche une routine (lisp ou vba) qui me permette de selectionner une polyligne fermée quand je clique à l'intérieur. Est-ce possible ?Si oui, comment ? Merci d'avance. PS: je ne sais pas si je poste dans le bon forum, mais je m'y perd un peu. Il n'y a pas de courage sans peur
(gile) Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 Salut, Voici un LISP pas très élégant (il y a peut-être plus simple mais je n'ai pas trouvé).Il ne fonctionne sous certaines conditions :- La polyligne doit être entièrement visible à l'écran- Le point de sélection ne doit pas être spécifié à l'intérieur d'un arc Nouvelle nouvelle version (defun c:selpline (/ pt size fenc inc loop point pmode ss ent test) (initget 1) (setq pt (getpoint "\nSpécifiez un point à l'intérieur de la polyligne: " ) size (getvar "viewsize") fenc (/ size 100) inc fenc loop T ) (entmake (list '(0 . "LINE") (cons 10 (trans pt 1 0)) (cons 11 (trans pt 1 0)) ) ) (setq point (entlast)) (while loop (if ( (setq loop nil) ) (if (and (setq ss (ssget "_F" (list pt (mapcar '+ pt (list 0 fenc 0)) ) '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1)) ) ) (setq ent (ssname ss (1- (sslength ss)))) (setq test (ssget "_CP" (mapcar '(lambda (pt) (trans pt ent 1) ) (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget ent) ) ) ) (list '(0 . "LINE") (assoc 10 (entget point)) ) ) ) ) (setq loop nil) (setq ent nil) ) (setq fenc (+ fenc inc)) ) (entdel point) (if ent (sssetfirst nil (ssadd ent)) ) (princ) ) [Edité le 1/10/2006 par (gile)][Edité le 1/10/2006 par (gile)] [Edité le 1/10/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
lecrabe Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 hello (gile) Je suis nul en Lisp mais j'ai l'impression que tu fais une sélection en mode _WP ?"Fenêtre normale Non capturante" pour tenter de "chopper" la polyligne ? Ai je compris ? Le Decapode "admiratif" Autodesk Expert Elite Team
(gile) Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 Salut lecrabe, En fait, dans une boucle, je fais d'abord une sélection en mode _Fence (Trajet) depuis le point spécifié en augmentant le trajet de 1/1000 de la taille de la vue active à chaque boucle jusqu'à ce que je trouve un polyligne fermée. Si une poly est trouvée je fais une selection en mode _WP avec les sommet de la dernière poly trouvée pour être sûr que le point spécifié est bien à l'intérieur, s'il n'y est pas on continue à boucler pour trouver une autre poly. Si aucune poly n'est trouvée la boucle s'arrête quand le trajet est égal à la hauteur de la vue (VIEWSIZE). PS : J'ai modifié le LISP, le trajet pour la sélection se faisait sur l'axe des X, je l'ai passé sur les Y puisque la limite est la hauteur de la vue. [Edité le 1/10/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
lecrabe Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 Hello Un seul mot : Waouhh = la Classe ! :) :D :cool: Comment as tu eu l'dée "démoniaque" de cet algorithme ? Le Decapode "abasourdi par (gile)" Autodesk Expert Elite Team
(gile) Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 Je ne l'ai pas fait en un seul coup, j'ai d'abord pensé au mode de sélection par un trajet qui augmente depuis le point spécifié, puis en faisant des essais j'ai imaginé que ce trajet pouvait rencontrer une autre polyligne fermée qui ne "contenait" pas ce point, alors j'ai imaginé un moyen pour écarter ce type de polyligne de la sélection. Je crois que le plus difficile en programmation est d'imaginer tout ce qui peut mettre en echec le programme, alors quand une routine semble fonctionner je fais des test pour essayer de la faire échouer. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 J'ai un peu modifier le LISP :- changement de l'incrémentation de la longueur du trajet de sélection (1/100 de la hauteur de la fenêtre au lieu de 1/1000) pour plus de rapidité d'exécution.- Changement de la variable PDMODE pour le point temporaire, et restauration de la valeur initiale. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 1 octobre 2006 Posté(e) le 1 octobre 2006 Que n'y avais-je pensé plus tôt ! Mieux que le changement de PDMODE : mode de sélection _CP (crossing polygon) et une ligne de longueur 0 pour remplacer le point temporaire. Le point peut être spécifié à l'intérieur de la polyligne ou sur la polyligne (avec les accrochages aux objets) Je re-modifie le LISP [Edité le 1/10/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
fabcad Posté(e) le 2 octobre 2006 Posté(e) le 2 octobre 2006 Je reponds au sujet par ces deux petites routines que j'ai créé.;-----------------------------------------------------------------(defun c:FERMEES ( / js-text)(setvar "cmdecho" 0)(setq FERMEES (ssget (list (cons 0 "LWPOLYLINE") (cons 70 1))))(sssetfirst FERMEES FERMEES));fin;-----------------------------------------------------------------(defun c:NON-FERMEES ( / js-text)(setvar "cmdecho" 0)(setq NON-FERMEES (ssget (list (cons 0 "LWPOLYLINE") (cons 70 0))))(sssetfirst NON-FERMEES NON-FERMEES));fin;----------------------------------------------------------------- A tester.... [Edité le 2/10/2006 par fabcad]
Fraid Posté(e) le 2 octobre 2006 Posté(e) le 2 octobre 2006 Bonjour, je viens de tester ton lisp Gilesi je remplace selpline par sp (c'est moin long)il ne fonctionne qu'une seul fois il faut que je le recharge pour que cela refonctionne :casstet: https://github.com/Fraiddd
benalto Posté(e) le 2 octobre 2006 Auteur Posté(e) le 2 octobre 2006 Bonjour à tous merci pour vos réponses, je vais essayer cela. Je vous tiens au courant.++ Il n'y a pas de courage sans peur
(gile) Posté(e) le 2 octobre 2006 Posté(e) le 2 octobre 2006 Salut Fraid, si je remplace selpline par sp (c'est moin long)il ne fonctionne qu'une seul fois Curieux, en effet ! Ça fonctionne chez moi. :casstet: Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 2 octobre 2006 Posté(e) le 2 octobre 2006 Désolé je raconte des bétisesmes polylignes suivantes n'etaient pas fermées :P du coup sa marche impécable il ne reste me plus qu'a fusionner cela avec pline bloc :casstet: https://github.com/Fraiddd
phil_vsd Posté(e) le 2 octobre 2006 Posté(e) le 2 octobre 2006 Bonjour à vous, J'ai pensé couplé cela avec pline_block mais je ne savais pas à quelle ligne l'insérer, ou quelle lignes remplacer... Il faut sans doute remplacer celles-là : ;; Sélection d'une entité (while (not (setq ent (car (entsel))))) Confirmation ? Merci ! "La ligne droite est le plus court chemin entre deux points, à condition que les deux points soient bien en face l'un de l'autre" P. Desproges.
(gile) Posté(e) le 2 octobre 2006 Posté(e) le 2 octobre 2006 J'ai apporté quelques améliorations au premier LISP, notamment en utilisant SelByObj, une routine qui permet de faire un jeu de sélection à partir d'un objet (polyligne cercle ellipse). La nouvelle version cherche une polyligne fermée par Capture avec des cercles concentriques autour du point spécifié. Chaque polyligne sélectionnée est testée toujours avec SelByObj pour vérifier si elle contient le point spécifié (les arcs des polylignes sont donc maintenant pris en compte).Si le point est contenu dans plusieurs polylignes c'est la plus proche du point qui est sélectionnée. Le LISP ne fonctionne que si la vue est parallèle au SCU courant et la polyligne contenue dans la vue. Le LISP est décomposé en une routine pour pouvoir l'utiliser dans d'autres LISP et une fonction d'appel. Nouvelle version (04/10/06) ;;; SELPLINE -Gilles Chanteau- 04/10/06 ;;; Sélection d'une polyligne par un point à l'intérieur ;;; Retourne un nom d'entité (ename) ou un message d'erreur (defun SelPlineByPoint (pt / size inc rad norm loop pick circle ss ent x_lst) (if (equal '(0 0) (reverse (cdr (reverse (getvar "VIEWDIR")))) 1e-9 ) (progn (setq size (getvar "viewsize") inc (/ size 200) rad inc norm (trans '(0 0 1) 1 0 T) loop T ) (entmake (list '(0 . "LINE") (cons 10 (trans pt 1 0)) (cons 11 (trans pt 1 0)) ) ) (setq pick (entlast)) (while loop (if ( (setq loop nil) ) (entmake (list '(0 . "CIRCLE") (cons 10 (trans pt 1 norm)) (cons 40 rad) (cons 210 norm) ) ) (setq circle (entlast)) (if (setq ss (SelByObj circle "Cp" '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1)) ) ) (progn (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n)))) (if (member ent x_lst) (ssdel ent ss) ) ) (if (setq ent (ssname ss 0)) (if (SelByObj ent "Wp" (list '(0 . "LINE") (cons 10 (trans pt 1 0)) (cons 11 (trans pt 1 0)) ) ) (setq loop nil) (setq x_lst (cons ent x_lst)) ) ) ) ) (entdel circle) (setq rad (+ rad inc)) ) (entdel pick) ent ) (alert "La vue doit être dans le plan du SCU courant") ) ) ;;; Fonction d'appel (defun c:selpline (/ pt) (sssetfirst nil nil) (initget 1) (setq pt (getpoint "\nSpécifiez un point à l'intérieur de la polyligne: " ) ) (if (setq ent (SelPlineByPoint pt)) (sssetfirst nil (ssadd ent)) (princ "\nPas polyligne trouvée.") ) (princ) ) Et SelByObj qui doit être chargée aussi :version corrigée (04/10/06) ;;; SelByObj -Gilles Chanteau- 04/10/06 ;;; Crée un jeu de sélection avec tous les objets contenus ou ;;; capturés par le polygone créé à partir de l'objet sélectionné ;;; Les courbes (cercles, ellipses, arcs de polylignes) sont segmentés ;;; Arguments : ;;; - un nom d'entité (ename) -cercle, ellipse, polyligne fermée- ;;; - un mode de sélection (Cp ou Wp) ;;; - un filtre de sélection (defun SelByObj (ent opt fltr / obj dist n lst prec dist p_lst) (vl-load-com) (setq obj (vlax-ename->vla-object ent)) (cond ((member (cdr (assoc 0 (entget ent))) '("CIRCLE" "ELLIPSE")) (setq dist (/ (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) 50 ) n 0 ) (repeat 50 (setq lst (cons (trans (vlax-curve-getPointAtDist obj (* dist (setq n (1+ n)))) 0 1 ) lst ) ) ) ) (T (setq p_lst (vl-remove-if-not '(lambda (x) (or (= (car x) 10) (= (car x) 42) ) ) (entget ent) ) ) (while p_lst (setq lst (append lst (list (cdr (assoc 10 p_lst))))) (if (/= 0 (cdadr p_lst)) (progn (setq prec (fix (* 50 (abs (cdadr p_lst)))) dist (/ (- (if (cdaddr p_lst) (vlax-curve-getDistAtPoint obj (cdaddr p_lst) ) (vlax-curve-getDistAtParam obj (vlax-curve-getEndParam obj) ) ) (vlax-curve-getDistAtPoint obj (cdar p_lst) ) ) prec ) n 0 ) (repeat (1- prec) (setq lst (append lst (list (trans (vlax-curve-getPointAtDist obj (+ (vlax-curve-getDistAtPoint obj (cdar p_lst) ) (* dist (setq n (1+ n))) ) ) 0 1 ) ) ) ) ) ) ) (setq p_lst (cddr p_lst)) ) (setq lst (mapcar '(lambda (x) (trans x 0 1)) lst)) ) ) (ssget (strcat "_" opt) lst fltr) ) Sinon, bien vu phil, pour utiliser SelPline dans Pline_Block, il faut remplacer :(while (not (setq ent (car (entsel))))) (if (= (cdr (assoc 0 (entget ent))) "LWPOLYLINE")par :(if (= (type (setq ent (selpline (getpoint "\nSpécifiez un point à l'intérieur de la polyligne: " ) ) ) ) 'ENAME )en utilisant la dernière version de SelPline.[Edité le 3/10/2006 par (gile)][Edité le 3/10/2006 par (gile)] [Edité le 4/10/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 3 octobre 2006 Posté(e) le 3 octobre 2006 J'ai corrigé un petit bug quand le "cercle de sélection" rencontrait certaine polylignes fermées ne conteneant pas le point spécifié. Il semble que ça fonctionne bien maintenant... Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 4 octobre 2006 Posté(e) le 4 octobre 2006 Des tests plus approfondis ont fait apparaître un dysfonctionnement dans des SCU différents du SCG. SelPline et SelByObj ont été corrigés en conséquence. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
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