Aller au contenu

Lisp inverser bloc (rotation 200gons)


Messages recommandés

Posté(e)

Bonjour,

Tout est dans le titre je souhaiterais une routine Lisp qui me permette de faire pareil que la commande inverser texte c'est à dire, 

Je sélectionne plusieurs blocs et j'aimerais leur appliquer une rotation de +200gons par rapport à leur rotation actuelle

ex mon bloc a une rotation de 132.1215g, le Lisp change en 332.1215g par rapport au point d'insertion du bloc.

J'aurais voulu la faire mais je ne m'y connais pas du tout et je ne vois pas du tout comment la faire

Merci bcp à tous, Félix

Posté(e)

Hello

Voici un Lisp "BROT" qui fait une rotation de TOUS les Blocs selectionnes par rapport a leur rotation originale !

Et dans le meme fichier, il y a aussi IDEM "BECH" pour l Echelle des Blocs ...

Routines : "BROT" et "BECH" - MERCI Gilles !

Bye, lecrabe

PS: LSP extrait de mon stock de 3001 routines

 

BROT____BECH.lsp

Autodesk Expert Elite Team

Posté(e) (modifié)

Coucou,

Essaye ceci (non testé) :

(defun c:RBx (/ r jsel i name entl rot)
  (if (null (setq r (getreal "\nValeur ajoutée pour la rotation <200> : ")))
    (setq r 200)
  )
  (and
    (setq jsel (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength jsel))
      (setq
        name (ssname jsel (setq i (1- i)))
        entl (entget name)
        rot (cdr (assoc 50 entl))
      )
      (entmod (subst (cons 50 (+ rot (angtof (vl-princ-to-string r) (getvar "AUNITS")))) (assoc 50 entl) entl))
    )
  )
  (princ)
)

Edit: Ou tout simplement les routines de Gile, précieusement conservées dans la bibliothèque de @lecrabe 😉

Bisous,
Luna

Modifié par Luna
Posté(e)
il y a 7 minutes, Luna a dit :

Coucou,

Essaye ceci (non testé) :

(defun c:RBx (/ r jsel i name entl rot)
  (if (null (setq r (getreal "\nValeur ajoutée pour la rotation <200> : ")))
    (setq r 200)
  )
  (and
    (setq jsel (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength jsel))
      (setq
        name (ssname jsel (setq i (1- i)))
        entl (entget name)
        rot (cdr (assoc 50 entl))
      )
      (entmod (subst (cons 50 (+ rot (angtof (vl-princ-to-string r) (getvar "AUNITS")))) (assoc 50 entl) entl))
    )
  )
  (princ)
)

Edit: Ou tout simplement les routines de Gile, précieusement conservées dans la bibliothèque de @lecrabe 😉

Bisous,
Luna

Salut Luna et merci, 

 

Bon on doit pas être très loin du résultat attendu, 

ca m'ajoute seulement 100gons 90° et non 200° 180°

De plus c'est possible de sélectionner le texte avant ou après le lancement de la commande ? 

Merci bcp !!

 

 

Posté(e)

Je viens de tester rapidement (avec AUNITS en degrés décimaux et aussi en grades) et chat fonctionne très bien chez moi...
J'ai mis 200 comme valeur par défaut (à supposer que AUNITS = 2 (grades), et si AUNITS = 0 (degrés décimaux) il faut mettre 180.
Et le (ssget) sans méthode spécifiée permet la pré-sélection si tu as PICKFIRST = 1. Donc si tu sélectionnes tes blocs en amont, le programme posera la question de la rotation puis utilisera ta pré-sélection directement. De plus tu as un filtre actif sur la sélection/pré-sélection pour que seuls les blocs soient considérés.

En tout cas, j'ai pas de soucis de mon côté >w<
As-tu essayé les programmes proposés par @lecrabe pour voir si cela te convient mieux éventuellement ?

Bisous,
Luna

Posté(e)
il y a 44 minutes, Luna a dit :

Je viens de tester rapidement (avec AUNITS en degrés décimaux et aussi en grades) et chat fonctionne très bien chez moi...
J'ai mis 200 comme valeur par défaut (à supposer que AUNITS = 2 (grades), et si AUNITS = 0 (degrés décimaux) il faut mettre 180.
Et le (ssget) sans méthode spécifiée permet la pré-sélection si tu as PICKFIRST = 1. Donc si tu sélectionnes tes blocs en amont, le programme posera la question de la rotation puis utilisera ta pré-sélection directement. De plus tu as un filtre actif sur la sélection/pré-sélection pour que seuls les blocs soient considérés.

En tout cas, j'ai pas de soucis de mon côté >w<
As-tu essayé les programmes proposés par @lecrabe pour voir si cela te convient mieux éventuellement ?

Bisous,
Luna

Je t'assure que ça me le tourne seulement de 90° ... Pourtant j'ai bien AUNIT=2.. 

tu aurais une idée ? 

J'avais regardé mais pas trouvé quelque chose qui me correspondait 100%  😉

 

EDIT : C'est bon il faut que je mette un angle de 300 par contre pour que ça me fasse un demi tour.. 

Dernière chose, je ne voudrais pas avoir a valider la rotation par exemple je sélectionne mes blocks, je lance la commande et ca tourne direct c'est possible ? 

Posté(e)
il y a une heure, lecrabe a dit :

Hello

Voici un Lisp "BROT" qui fait une rotation de TOUS les Blocs selectionnes par rapport a leur rotation originale !

Et dans le meme fichier, il y a aussi IDEM "BECH" pour l Echelle des Blocs ...

Routines : "BROT" et "BECH" - MERCI Gilles !

Bye, lecrabe

PS: LSP extrait de mon stock de 3001 routines

 

BROT____BECH.lsp 1 Ko · 0 téléchargement

Je n'avais pas vu ta réponse, merci, je voudrais juste que la rotation soit fixée à 200grade comme ça je clic sur un icone personnalisé, je sélectionne, je valide et hop tout est inversé

Posté(e)

Peux-tu me fournir un .dwg d'exemple dans lequel cela ne fonctionne pas...car mathématiquement parlant, je suis perplexe >n<

Ensuite, pour ta demande il suffit de faire moins, moi je propose un programme qui puisse être utile à tous ^^"
Donc pour supprimer la question, il suffit de remplacer

  (if (null (setq r (getreal "\nValeur ajoutée pour la rotation <200> : ")))
    (setq r 200)
  )

par

  (setq r 200)

et c'est tout... Voir plus proprement (pour conserver la possibilité si jamais) en rajoutant uniquement un point-virgule sur la ligne 1 et 3 (pour conserver la 2 uniquement) :

;  (if (null (setq r (getreal "\nValeur ajoutée pour la rotation <200> : ")))
    (setq r 200)
;  )

Bisous,
Luna

Posté(e)

Hello

NON la routine BROT ne fixe pas une facteur de rotation quelque soit la rotation originale !

Sinon je suis aussi perplexe que Luna !

Bye, lecrabe

 

Autodesk Expert Elite Team

Posté(e)

 

 

Salut Luna, 

voici le dwg la lisp chargée j'ai rajouté 300 pour l'inversion

Et merci bcp pour le reste !!! J'essaie tout à l'heure, 

Par contre ça ne fonctionne pas sur le bloc rouge ... pourquoi ? 

Merci Lecrabe pour ta réponse

La bise

Exemple.dwg

Posté(e)

Oki, je viens de tester sur ton .dwg et.....bah le soucis ne vient pas de moi !! C'est ton .dwg qui a un soucis mais je n'arrive pas à comprendre la raison.
En clair dans un fichier vierge, j'ai (si le format est un grade, degrés, radians, ...)

(angtof "0")
0.0

Mais sur ton fichier j'ai

(angtof "0")
1.5708

donc à cause de ce décalage d'un demi pi, cela fausse les rotations bien évidemment....

Je viens potentiellement de trouver une explication : NORTHDIRECTION ! Est-ce une variable système qui te parle ?
Si oui, je ne peux rien y faire car je penser pouvoir faire

(setq r (angtof (vl-princ-to-string r) (getvar "AUNITS")))
(+ r (getvar "NORTHDIRECTION"))

mais malheureusement, peut importe la valeur de NORTHDIRECTION (si on lance la commande associée en tant qu'utilisateur) la ligne

(getvar "NORTHDIRECTION")

renvoie toujours 0.0 !

Donc je ne peux pas y faire grand chose pour prendre en compte cela, car cette variable influe directement la liste DXF des entités (par rapport à la palette des propriétés).

Autrement, pour ce qui est du bloc rouge, le programme fonctionne mais je n'avais pas prévu les blocs avec attributs donc il faut rajouter un ATTSYNC pour les blocs

Bisous,
Luna

  • Upvote 1
Posté(e)
il y a 3 minutes, Luna a dit :

Oki, je viens de tester sur ton .dwg et.....bah le soucis ne vient pas de moi !! C'est ton .dwg qui a un soucis mais je n'arrive pas à comprendre la raison.
En clair dans un fichier vierge, j'ai (si le format est un grade, degrés, radians, ...)

(angtof "0")
0.0

Mais sur ton fichier j'ai

(angtof "0")
1.5708

donc à cause de ce décalage d'un demi pi, cela fausse les rotations bien évidemment....

Je viens potentiellement de trouver une explication : NORTHDIRECTION ! Est-ce une variable système qui te parle ?
Si oui, je ne peux rien y faire car je penser pouvoir faire

(setq r (angtof (vl-princ-to-string r) (getvar "AUNITS")))
(+ r (getvar "NORTHDIRECTION"))

mais malheureusement, peut importe la valeur de NORTHDIRECTION (si on lance la commande associée en tant qu'utilisateur) la ligne

(getvar "NORTHDIRECTION")

renvoie toujours 0.0 !

Donc je ne peux pas y faire grand chose pour prendre en compte cela, car cette variable influe directement la liste DXF des entités (par rapport à la palette des propriétés).

Autrement, pour ce qui est du bloc rouge, le programme fonctionne mais je n'avais pas prévu les blocs avec attributs donc il faut rajouter un ATTSYNC pour les blocs

Bisous,
Luna

Ha ouais c'est bizarre elle est définie a 100 chez moi et comme tu dis peu importe la valeur il faut que ma lisp soit a 300 pour que ça fonctionne... Bref c'est tout ce que je voulais, 

Non cette variable ne me dit rien du tout...

dernière interrogation ?

 


	(setq 
		jeusel (ssget '((0 . "TEXT,MTEXT,INSERT")))
		incr 0
	)

;*******************************************

		(if (= (cdr (assoc 66 entcodes)) 1)			; si c'est un bloc avec attributs
			(progn
				(setq
					angobj (JBR2G (cdr (assoc 50 entcodes)))
					angrot (- 400 (- angvue angobj))
				)
				(command "_.rotate" entname "" (cdr (assoc 10 entcodes)) angrot)
			)
			(progn
				(setq entcodes (subst (cons 50 (JBG2R angvue)) (assoc 50 entcodes) entcodes))
				(entmod entcodes)
			)
		)
		(setq incr (1+ incr))
	)

j'ai trouvé ça et je n'ai pas besoin de faire ATTSYNC avec cette lisp tu sais pk ? 

Posté(e)

Parce que la rotation est effectuée par la commande ROTATION si le bloc possède des attributs, autrement on modifie la liste DXF de l'entité pour appliquer la rotation sans utiliser de (command), car l'utilisation de cette fonction ralenti considérablement le temps d'exécution du programme !

Le code que je t'ai fourni, comme je l'ai précisé, est non testé car écrit à la va-vite en 2min. Donc forcément je ne me suis pas amusé à prévoir tous les cas de figures comme je ferais dans des programmes plus complexes.

Bisous,
Luna

Posté(e)

En reprenant le code de @Luna sous cette forme, cela va mieux?

(defun c:RBx ( / r jsel i name entl rot)
  (defun update_block (block_record ang pt / s_e dxf_e)
    (if (/= (getvar "ATTMODE") 1) (setvar "ATTMODE" 1))
    (setq s_e block_record)
    (while (/= (cdr (assoc 0 (entget (setq s_e (entnext s_e))))) "SEQEND")
      (setq dxf_e (entget s_e))
      (if (eq (cdr (assoc 0 dxf_e)) "ATTRIB")
        (progn
          (entmod (setq dxf_e (subst (cons 10 (polar pt (+ (angle pt (cdr (assoc 10 dxf_e))) (- ang (cdr (assoc 50 dxf_e)))) (distance pt (cdr (assoc 10 dxf_e))))) (assoc 10 dxf_e) dxf_e)))
          (entmod (setq dxf_e (subst (cons 50 ang) (assoc 50 dxf_e) dxf_e)))
        )
      )
    )
    (entupd block_record)
  )
  (if (null (setq r (getorient (strcat "\nValeur ajoutée pour la rotation <" (angtos (+ pi (getvar "ANGBASE")))"> : "))))
    (setq r pi)
  )
  (and
    (setq jsel (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength jsel))
      (setq
        name (ssname jsel (setq i (1- i)))
        entl (entget name)
        rot (cdr (assoc 50 entl))
      )
      (entupd (cdar (entmod (subst (cons 50 (+ rot r)) (assoc 50 entl) entl))))
      (update_block name (+ rot r) (cdr (assoc 10 entl)))
    )
  )
  (princ)
)

 

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

Posté(e)
il y a 21 minutes, bonuscad a dit :

En reprenant le code de @Luna sous cette forme, cela va mieux?

(defun c:RBx ( / r jsel i name entl rot)
  (defun update_block (block_record ang pt / s_e dxf_e)
    (if (/= (getvar "ATTMODE") 1) (setvar "ATTMODE" 1))
    (setq s_e block_record)
    (while (/= (cdr (assoc 0 (entget (setq s_e (entnext s_e))))) "SEQEND")
      (setq dxf_e (entget s_e))
      (if (eq (cdr (assoc 0 dxf_e)) "ATTRIB")
        (progn
          (entmod (setq dxf_e (subst (cons 10 (polar pt (+ (angle pt (cdr (assoc 10 dxf_e))) (- ang (cdr (assoc 50 dxf_e)))) (distance pt (cdr (assoc 10 dxf_e))))) (assoc 10 dxf_e) dxf_e)))
          (entmod (setq dxf_e (subst (cons 50 ang) (assoc 50 dxf_e) dxf_e)))
        )
      )
    )
    (entupd block_record)
  )
  (if (null (setq r (getorient (strcat "\nValeur ajoutée pour la rotation <" (angtos (+ pi (getvar "ANGBASE")))"> : "))))
    (setq r pi)
  )
  (and
    (setq jsel (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength jsel))
      (setq
        name (ssname jsel (setq i (1- i)))
        entl (entget name)
        rot (cdr (assoc 50 entl))
      )
      (entupd (cdar (entmod (subst (cons 50 (+ rot r)) (assoc 50 entl) entl))))
      (update_block name (+ rot r) (cdr (assoc 10 entl)))
    )
  )
  (princ)
)

 

C'est 100% ce que je voulais..  Un immense merci @bonuscad du coup tu sais d'où venait le fait que le 200g ne fonctionnait pas pour moi ? 

Merci à toi aussi @Luna

Posté(e)
Citation

du coup tu sais d'où venait le fait que le 200g ne fonctionnait pas pour moi ? 

Tout venait de là : (getvar "ANGBASE")

Pour être plus explicite ton dessin est défini en grade avec l'origine des angles au Nord et tournant dans le sens Horaire (je n'ai d’ailleurs pas vérifier cela vu que 200 c'est la moitié du cercle entier, donc ça ne change rien, mais  pour des valeurs quelconques cela ne sera peut être pas correct, dans ce cas s'appuyer sur la variable ANGDIR)

La base d'Autocad fonctionne en radians avec l'origine à l'Est et dans le sens anti-horaire, il faut faire les conversions adéquates!

Posté(e)
il y a une heure, Luna a dit :

Coucou @bonuscad,

Quand je vois toutes les fonctions auxquelles je n'ai pas pensé, je me sens un peu bête... ^^"
C'est de suite un peu plus propre 😉

Merci,
Luna

Franchement avec la qualité de tes réponses et les codes que tu publies, il n'y a pas de quoi se sentir bête...

On passe parfois à côté de choses évidentes, ou on prends des voies tortueuse, et cela m'arrive aussi 🥲

Posté(e)

@Olivier Eckmann,

Yes j'avoue que je n'ai pas encore été confronté à la récupération de valeur angulaire au cours de mes pérégrinations donc je connaissais ANGBASE et ANGDIR (notamment à cause de SNAPANG) mais sans vraiment y prêter attention...Mais c'est bon à savoir pour les prochaines fois !

il y a 14 minutes, Invité bonuscad a dit :

Franchement avec la qualité de tes réponses et les codes que tu publies, il n'y a pas de quoi se sentir bête...

On passe parfois à côté de choses évidentes, ou on prends des voies tortueuse, et cela m'arrive aussi

Vui j'avoue que j'ai souvent tendance à me torturer l'esprit devant des problèmes simplissimes parfois xD
Mais bon, au final cela devient limite une signature dans le langage de programmation. Lorsque je lis les programmes de LeeMac par exemple, on le reconnaît très vite ^^

En tous cas, j'aime beaucoup la fonction (update_block) pour limiter l'utilisation de ATTSYNC, je ne savais pas que l'on pouvait le faire ainsi !
C'est souvent le soucis que j'ai parfois, savoir dans quels cas la fonction (command) est obligatoire et dans lesquels elle peut être habilement contournée.

Bisous,
Luna

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • 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é