Aller au contenu

Sélectionner une ligne de cotes en une seule manip ?


Messages recommandés

Posté(e)

Salut,

sélectionner toutes les cotes qui lui sont colinéaires

 

Je ne sais pas si la proposition que je vais te faire va te satisfaire.

 

En m'appuyant sur l'aide du code DXF 70 des DIMENSION

70

Type de cote :

 

Les valeurs comprises entre 0 et 6 sont des valeurs entières représentant le type de cote. Les valeurs 32, 64 et 128 sont des valeurs de bit, ajoutées aux valeurs entières (la valeur 32 est systématiquement définie dans les versions 13 et ultérieures)

 

0 = Pivoté, horizontal ou vertical ; 1 = Aligné

 

2 = Angulaire ; 3 = Diamètre ; 4 = Rayon

 

5 = Angulaire à 3 points ; 6 = Superposé

 

32 = Indique que la référence de bloc (code de groupe 2) est référencée uniquement d'après cette cote.

 

64 = Type superposé. Il s'agit d'une valeur binaire (bit 7) utilisée seulement avec la valeur entière 6. Si elle est définie, l'ordonnée est de type X, sinon, elle est de type Y.

 

128 = Il s'agit d'une valeur binaire (bit 8) ajoutée aux autres valeurs du groupe 70 si le texte de cote est placé sur un emplacement défini par l'utilisateur plutôt que sur l'emplacement par défaut

 

 

Donc si tu ne veux sélectionner que des cotes Pivoté, horizontale ou verticale, ce type de filtre devrait fonctionner:

 

(sssetfirst nil (ssget "_X" '((0 . "DIMENSION") (-4 . "&=") (70 . 0))))

 

Edit:

 

Après quelque essais, je me suis rendu compte qu'il vaut mieux être exclusif pour que le filtre fonctionne bien. Celui qui suit sera plus distinctif que le précédent

 

(sssetfirst nil
(ssget "_X"
	'(
		(0 . "DIMENSION")
		(-4 . "				(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
		(-4 . "AND>")
	)
)
)

 

[Edité le 28/3/2011 par bonuscad]

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

Posté(e)

Merci pour ta réponse.

J'avais que c'est un peu au-delà de mes connaissances du LISP.

J'ai imaginé qu'il fallait intégrer le code à une routine :

 

(defun c:scc ()
(sssetfirst nil
(ssget "_X"
	'(
		(0 . "DIMENSION")
		(-4 . "				(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
		(-4 . "AND>")
	)
)
)
)

 

Problème : dès que je lance la routine, tout le dessin est sélectionné.

 

J'ai faux où ?

 

Merci !

Posté(e)

L'exemple que je t'ai donné, si tu le colle directement en ligne de commande, doit activer les grips sur les cotes concernées.

 

Pour l'utilisation dans un lisp, il serait mieux d'abandonner (sssetfirst) et plutôt assimiler le jeux de sélection (ssget) à une variable genre (setq js (ssget ........))

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

Posté(e)

Problème : dès que je lance la routine, tout le dessin est sélectionné.

 

J'ai essayé ta fonction (defun c:scc) , pour moi pas de souci elle fonctionne comme mon code proposé (ne sélectionne que les cotes linéaires).

 

Donc je vois pas où cela pêche... à part un problème de version (je n'ai pas 2010), en tout cas sous 2008 ou 2009 pas de problème. En conséquence, je ne peux plus t'aider !

 

Il faut dire qu'Autodesk me surprends sur l'utilisation des bits pour les cotations.

Ils ont mélangé des valeur entières (0 1 2 3 4 5 6) avec des bits de contrôles (32 64 128), il devient donc ardu d'utiliser des opérations booléennes sur de telles valeurs entière pour récupérer un type de cotation. :casstet:

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

Posté(e)

Salut bryce

 

sélectionner toutes les cotes dont les lignes de cotes sont alignées

 

Ben, il me semble que le plus simple et de remplacer (ssget "_X" filtre) par simplement (ssget filtre), cela lui laisse la possibilité de faire soit une/des fenêtres, captures ou simplement individuelle.

 

Oui, mais avec étirer, on sélectionne toujours des tas de trucs auxquels on ne veut pas toucher

 

Son principal soucis était d'avoir une sélection filtrée pour ne pouvoir sélectionner que les cotes.

 

Après, il peut améliorer encore le filtre (Style de cotation: DXF 3) (Calque DXF 8) et que sais je encore?

 

J'ai voulu essayé un truc plus généraliste comme ce qui suit mais ça ne fonctionne pas (problème booléen)

(defun c:same_dim_move ( / js dxf_ent l_70)
 (princ "\nSélectionnez un type de cotation à gripperr: ")
 (while (null (setq js (ssget "_+.:E:S" '((0 . "DIMENSION")))))
   (princ "\nAttend une sélection de cotation!")
 )
 (setq
   dxf_ent (entget (ssname js 0))
   l_70 (vl-remove (rem (rem (rem (cdr (assoc 70 dxf_ent)) 32) 64) 128) '(6 5 4 3 2 1 0))
 )
 (sssetfirst nil
   (ssget "_X"
     (append
       '((0 . "DIMENSION"))
       (list (assoc 8 dxf_ent))
       (list (assoc 3 dxf_ent))
       (list (assoc 410 dxf_ent))
       '((-4 . "        (apply
         'append
         (mapcar
           '(lambda (x) (list (cons -4 "")))
           l_70
         )
       )
       '((-4 . "AND>"))
     )
   )
 )
)

 

Si bryce ou d'autres se sentent de trouver une autre alternative ...

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

Posté(e)

Ach so ! J'ai compris que nous ne nous étions pas compris.

 

Je souhaite sélectionner non pas toutes les cotes linéaires, mais les cotes colinéaires à une cote, càd les cotes qui prolongent (à droite et à gauche) une cote donnée.

 

Par exemple, si je clique sur la largeur de la salle-à-manger, la routine sélectionne aussi la cote de la cloison de la cuisine et la cote de la cuisine, et la cote du mur entre cuisine et escalier de l'immeuble, et ainsi de suite pour toutes les cotes dont la ligne de cote prolonge la 1ère cote sélectionnée.

 

Merci en tous cas pour tes réponses.

Posté(e)

Ach so ! J'ai compris que nous ne nous étions pas compris.

 

Si j'avais compris. Pour moi si les cotes sont colinéaires, il est simple de faire une fenêtre de sélection englobant celle-ci et de ne filtrer que les cotes linéaires (ca fait simplement un click de plus, faut pas pousser). Comme j'ai dis en supprimant l'option "_x" qui correspond à tous le dessin.

 

(command "_.move"
(ssget 
	'(
		(0 . "DIMENSION")
		(-4 . "				(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
		(-4 . "AND>")
	)
)
""
)

 

Une fenêtre autour de tes cotes colinéaires et celles-ci sont sélectionnées...

Après choisir une cote (1 click) et choisir par fenêtre (2 clicks)... :casstet:

Je te laisse les sélectionner une par une :mad:

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

Posté(e)

Merci pour ta réponse (et merci à Bryce aussi).

 

En effet, je n'avais pas compris que tu m'avais compris, mais maintenant je ne comprends pas comment marche ce que tu proposes.

 

Quand j'exécute ta routine, je clique sur une une cote, puis je fais une fenêtre de sélection. Les cotes sont bien filtrées, mais toutes les cotes restent sélectionnées.

 

Moi pas comprendre.

 

Voilà mon code :

 

(defun c:scc ()
(command "_.move"
(ssget 
	'(
		(0 . "DIMENSION")
		(-4 . "				(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
			(-4 . "")
		(-4 . "AND>")
	)
)
""
)
)

 

[Edité le 29/3/2011 par gloub]

Posté(e)

Bon, j'ai résolu le problème d'un filtre plus générique.

 

La routine va te demander de sélectionner une cote modèle qui va servir à monter le filtre.

Le filtrage va se faire sur son calque, son style de cote, l'espace utilisé (papier/objet) et le type de cotation: linéaire, aligné, angulaire, diamètre, rayon, angulaire 3pt et superposé (X Y).

 

Au second message choix des objets, tu as la possibilité de faire la ou les sélections classiques, et dès que tu auras validé ces sélections, tu sera invité à fournir le point de base de déplacement et le nouveau point (commande déplacer classique)

 

(defun c:scc ( / js dxf_ent dxf_70)
 (princ "\nSélectionnez un type de cotation modèle à griper: ")
 (while (null (setq js (ssget "_+.:E:S" '((0 . "DIMENSION")))))
   (princ "\nAttend une sélection de cotation!")
 )
 (setq
   dxf_ent (entget (ssname js 0))
   dxf_70 (assoc 70 dxf_ent)
 )
 (setq js
   (ssget
     (list
       '(0 . "DIMENSION")
       (assoc 8 dxf_ent)
       (assoc 3 dxf_ent)
       (assoc 410 dxf_ent)
       '(-4 . "          dxf_70
         (cons 70 (+ (cdr dxf_70) 128))
         (cons 70 (+ (cdr dxf_70) 64))
         (cons 70 (- (cdr dxf_70) 128))
         (cons 70 (- (cdr dxf_70) 64))
       '(-4 . "OR>")
     )
   )
 )
 (if js (command "_.move" js "") (prin1))
)

 

Pour faire plus souple encore (dans le sens verbe action, l'action étant choisi après la mise en grips ce qui laisse encore plus de possibilité d'action)

(defun c:sel_same_dim ( / js dxf_ent dxf_70)
 (princ "\nSélectionnez un type de cotation modèle à griper: ")
 (while (null (setq js (ssget "_+.:E:S" '((0 . "DIMENSION")))))
   (princ "\nAttend une sélection de cotation!")
 )
 (setq
   dxf_ent (entget (ssname js 0))
   dxf_70 (assoc 70 dxf_ent)
 )
 (sssetfirst
   nil
   (ssget "_X"
     (list
       '(0 . "DIMENSION")
       (assoc 8 dxf_ent)
       (assoc 3 dxf_ent)
       (assoc 410 dxf_ent)
       '(-4 . "          dxf_70
         (cons 70 (+ (cdr dxf_70) 128))
         (cons 70 (+ (cdr dxf_70) 64))
         (cons 70 (- (cdr dxf_70) 128))
         (cons 70 (- (cdr dxf_70) 64))
       '(-4 . "OR>")
     )
   )
 )
 (prin1)
)

 

[Edité le 29/3/2011 par bonuscad]

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

Posté(e)

Merci beaucoup pour ton investissement !

 

La routine SCC marche…presque : quand je sélectionne des entités par une fenêtre, les cotes sont filtrées, mais le jeu de sélection conserve les cotes perpendiculaires à la 1ère cote sélectionnée…

 

Par ailleurs, je ne sais pas comment "implémenter" la version "verbe action".

Posté(e)

mais le jeu de sélection conserve les cotes perpendiculaires à la 1ère cote

 

Pour les cotes linéaires, il n'y a pas moyen de différencier celle faites dans le sens des X et celle des Y .Avec les superposées (comprendre coordonnées) cela est possible.

 

Seule solution (affiner ta sélection fenêtre, ou avec MAJ-Click sur la cote en trop pour la retirer de la sélection)

 

Par ailleurs, je ne sais pas comment "implémenter" la version "verbe action"

Si tu n'es pas habitué aux grips...

Une fois les objets "gripés" tu lance une commande standard (déplacer,copier,changer,effacer...), les objet gripper seront automatiquement soumis à la commande que tu as lancé. Tu peux leur faire subir plusieurs commandes successives. Esc pour "dégriper" les objets.

Tu peux même changer directement leurs états par les barres déroulantes (calques, couleur, typeligne, épaisseur)

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

Posté(e)

Je me suis repenché sur ta demande, et cette fois je pense (j'espère) d'après mes tests que le résultat devrait être assez fiable...

 

(defun c:scc( / ) (sssetfirst nil (scc)) (princ))
; Sélectionne une chaîne de cotes (cotes linéaires ou alignées)
;
; Taper SCC à l'invite "Commande: " ou (SCC) à l'invite "Choix des objets: ".
; La commande peut être répétée pour cumuler plusieurs sélections.
;
; La sélection est stockée dans la variable globale *scc*, et peut être rappelée
; en tapant !*scc* à l'invite "Choix des objets: ".
;
; Brice Studer, mars 2011

(defun scc (/ *error* dim ent lp bp bp2 ang tss i lpi ang2 )

(setq precision 2) ; précision d'alignement des cotes, entier de 1 (le plus tolérant) à 8 (le plus précis)

;~~~~~~~~~~~~~~~~~~~~~~~~~
(defun *error* (msg)
(and msg
	(or
		(member (strcase msg) '("FUNCTION CANCELLED" "QUIT / EXIT ABORT" "FONCTION ANNULEE" "QUITTER / SORTIR ABANDON"))
		(princ (strcat "\nErreur : " msg))
	)
)
(if tss (setq tss nil))
(princ)
)

(setq *scc* (cadr (ssgetfirst)))

(while
	(not
		(and
			(setq dim (car (entsel "\nChoisissez une cote de la chaîne à sélectionner: " )) )
			(eq "DIMENSION" (cdr (assoc 0 (setq ent (entget dim)) ) ) )
			(member (cdr (assoc 70 ent)) '(32 33 160 161))
		);and
	);not
	(princ "\nL'objet sélectionné n'est pas une cote linéaire ou alignée !")
);while

(if *scc*
	(ssadd dim *scc*)
	(setq *scc* (ssadd dim))
)

(setq	lp (cdr (assoc 10 ent))
		bp (trans (cdr (assoc 14 ent)) 0 1)
		bp2 (trans (cdr (assoc 13 ent)) 0 1) )

(if (member (cdr (assoc 70 ent)) '(32 160))
		(setq ang (angtof (angtos (angle
				(trans lp 0 1)
				(trans (polar lp (cdr (assoc 50 ent)) 1) 0 1)
			) 3 precision))
		)
		(setq ang (angtof (angtos (angle bp bp2) 3 precision)))
)

(setq	tss (ssget "_X" (list (cons 0 "DIMENSION") (cons 410 (getvar "CTAB")) (cons -4 "")) )
		i 0 )
(ssdel dim tss)
(if tss
	(progn
		(setq lp (trans lp 0 1))
		(repeat (sslength tss)
			(setq	lpi (trans (cdr (assoc 10 (entget (ssname tss i)))) 0 1)
					ang2 (angle lp lpi) )

			(if (or
					(= ang (angtof (angtos ang2 3 precision)) )
					(= ang (angtof (angtos (- ang2 PI) 3 precision)) )
				)
				(ssadd (ssname tss i) *scc*)
			)
			(setq i (1+ i))
		);repeat
		(setq tss nil)
	)
)
*scc*
);defun

(princ "\nTaper SCC à l'invite \"Commande: \"")
(princ "\nou (SCC) à l'invite \"Choix des objets: \" ")
(princ)

 

http://www.creao.fr/uploads/lisp/sel_chaine_cotes.lsp

 

 

 

[Edité le 30/3/2011 par bryce]

Posté(e)

Bryce,

 

Juste une petite suggestion, pour définir à la fois une commande et une fonction utilisable pour répondre à l'invite "Choix des objets: ", je préfère définir une fonction qui retourne un jeu de sélection et appeler cette fonction dans la commande.

 

Un exemple simple, pour sélectionner tous les objets sur le même calque que le calque cible :

 

(defun ssl (/ ss ent)
 (if
   (or
     (and
(setq ss (cadr (ssgetfirst)))
(= 1 (sslength ss))
(setq ent (ssname ss 0))
     )
     (setq ent (car (entsel)))
   )
    (ssget "_X" (list (assoc 8 (entget ent))))
 )
)

(defun c:ssl () (sssetfirst nil (ssl)) (princ))

 

On peut utiliser la commande SSL pour faire une sélection ou entrer (ssl) à l'invite "Choix des objets: " des commandes d'édition.

 

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

Posté(e)

Merci du tuyau (gile) ! :)

Ca tombe bien, c'était justement une question que je voulais poser dans le forum "Débuter en LISP".

 

Il n'y a pas un moyen de pouvoir utiliser une commande Lisp (sans les () ) de façon transparente pour sélectionner des objets, de la même façon qu'avec 'filter par exemple ?

Posté(e)

Il n'y a pas un moyen de pouvoir utiliser une commande Lisp (sans les () ) de façon transparente pour sélectionner des objets, de la même façon qu'avec 'filter par exemple ?

 

Pas à ma connaissance, c'est la présence d'une parenthèse ouvrante comme premier caractère qui appelle l'interpréteur LISP.

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

Posté(e)

l n'y a pas un moyen de pouvoir utiliser une commande Lisp (sans les () ) de façon transparente pour sélectionner des objets, de la même façon qu'avec 'filter par exemple ?

 

Si c'est possible.

Dans ton cas (defun c:scc .....) de la manière la plus classique, et bien en transparence tu rajoute simplement la quote soit 'SCC dans une commande standard en cours.

 

Il faut quand même que le code soit conçu pour répondre à ce genre d'appel. Je dirais de manière générale qu'il ne doit pas contenir de (command) en son sein.

 

Pour l'exemple (inutile) ce genre de fonction marcherais très bien

(defun c:xmil ( / p1 p2 p)
(prompt "\nPoint milieu entre ")
(setq p1 (getpoint "premier point : "))
(setq p2 (getpoint p1 "\nsecond point : "))
(setvar "osmode" (+ 16384 (rem (getvar "osmode") 16384)))
(setq p (list (/ (+ (car p1) (car p2)) 2)
              (/ (+ (cadr p1) (cadr p2)) 2)
              (/ (+ (caddr p1) (caddr p2)) 2)
	)
)
(setvar "lastpoint" p)
)

 

Commande: ligne Spécifiez le premier point: [surligneur]'xmil[/surligneur]

 

Point milieu entre premier point :

second point :

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

Posté(e)

De mon côté, je n'ai jamais réussi à entrer une commande définie en LISP de manière transparent à l'invite "Choix des objets: " d'une commande d'édition.

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

Posté(e)

Je dirais de manière générale qu'il ne doit pas contenir de (command) en son sein.

 

N'ayant jamais trop testé ce mode de transparence avec des fonction lisp, il est possible que les fonctions (ssget) (entsel) soit problématique.

Pour faire court, je pense que l'on peut réserver ce mode qu'avec des fonctions de base du lisp.

L'appel par (scc) est certainement plus approprié que 'scc pour l'évaluation par l'interpréteur.

 

Néanmoins cela reste possible mais avec des restrictions que je ne connais pas vraiment.

 

 

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

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é