[AUTOCAD] Insertion de blocs aux abscisses min et max d'une sélection

[AUTOCAD] Insertion de blocs aux abscisses min et max d'une sélection

SET040
Advocate Advocate
1 187 Visites
12 Réponses
Message 1 sur 13

[AUTOCAD] Insertion de blocs aux abscisses min et max d'une sélection

SET040
Advocate
Advocate

Bonjour,

 

Je souhaiterais insérer automatiquement un bloc à la coordonnée Xmin/Ymin d'une sélection.

Et un autre bloc à la coordonnées Xmax/Ymin de cette même sélection.

 

Je joins un .dwg afin de mieux visualiser ma demande. Ma sélection sera toujours, comme dans l'exemple du dwg, constituée de 4 lignes verticales simple

 

Cela me permettrait d'habiller plus rapidement des "profils en travers", parce qu'il se compte par centaines dans certaines de mes projet.

 

D'avance, un tout grand merci 🙂

0 J'aime
Solutions acceptées (1)
1 188 Visites
12 Réponses
Replies (12)
Message 2 sur 13

-didier-
Advisor
Advisor

Bonjour @SET040 

Je pense que c'est faisable sans grande complexité, mais je pense aussi qu'on peut faciliter les choses.

Ma question est :

Est-ce que les quatre lignes ont toujours le même espacement ?

Si c'est le cas, il est possible d'en faire un bloc avec le point d'insertion au Xmin,Ymin

Autrement dit sur le point bas gauche de la ligne de gauche.

Et dans ce cas, faire un LSP devient très aisé.

Ou bien, en natif, redéfinir le bloc avec les quatre lignes en incluant les textes à insérer.

 

Merci de me tenir au courant pour savoir dans quelle direction travailler pour proposer une solution.

Amicalement

 

Éternel débutant.. my site for learning : Programmer dans AutoCAD

DA

EESignature

0 J'aime
Message 3 sur 13

SET040
Advocate
Advocate

Bonjour @-didier- ,

 

En fait, les lignes 1-2 ont toujours le même écart (il s'agit d'un écart entre des rails de tram = 1.430m)

Pareil, pour les lignes 3-4.

 

En revanche, l'écart entre 1-2 et 3-4 est variable. D'où mon approche d'insérer 2 blocs distincts.

 

Avant que je te perde dans mes explications, voici un dessin version "finale" d'un profil en travers 🙂

0 J'aime
Message 4 sur 13

Y.AUBRY
Advisor
Advisor

Bonjour,

 

Je pense qu'en modifiant légèrement sur le lisp SmalestRectangle de Kent Cooper, il est facilement possible de récupérer les coordonnées XMin, XMax (YMin) de la sélection, et donc d'ensuite insérer des blocs (merci de nous livrer le bloc ou au moins de nous donner son nom, emplacement du bloc source sur ton PC/serveur) au niveau de ces points.

 

 

;;  SmallestRectangle.lsp [command name: SR]
;;  To draw the Smallest orthogonal Rectangle around a User-
;;    selected group of objects.  Draws on the current Layer.
;;  Kent Cooper, 27 February 2013
(defun C:SR (/ obb oLL oUR ss LL UR); = Smallest Rectangle
  (defun obb (ent); = Object's Bounding Box corners
    (vla-getboundingbox (vlax-ename->vla-object ent) 'minpt 'maxpt)
    (setq
      oLL (vlax-safearray->list minpt); Object's Lower Left
      oUR (vlax-safearray->list maxpt); Object's Upper Right
    ); setq
  ); defun -- obb
  (vl-load-com)
  (prompt "\nTo draw the Smallest Rectangle around them,")
  (setq ss (ssget))
  (obb (ssname ss 0))
  (setq LL oLL UR oUR); initial overall LL & UR [of first object]
  (ssdel (ssname ss 0) ss)
  (repeat (sslength ss)
    (obb (ssname ss 0))
    (setq
      LL (mapcar 'min oLL LL); least of each component
      UR (mapcar 'max oUR UR); greatest of each component
    ); setq
    (ssdel (ssname ss 0) ss)
  ); repeat
  (command "_.rectangle" "_none" LL "_none" UR)
  (princ)
); defun -- C:SR

 

 https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/the-smallest-rectangle-enclosing-sel...

 

A+ Yoan

Yoan AUBRY

EESignature

0 J'aime
Message 5 sur 13

-didier-
Advisor
Advisor

Bonjour @SET040 

 

Il y a deux/trois choses que je ne comprends pas sur ton dessin.

Tout d'abord : Avec quel logiciel sont dessinés les profils en travers ?

Contacte-moi par message privé, s'il te plaît, car les messages risquent de se multiplier.

On mettra la solution trouvée pour la connaissance de tous une fois les détails réglés.

Amicalement

Éternel débutant.. my site for learning : Programmer dans AutoCAD

DA

EESignature

0 J'aime
Message 6 sur 13

Y.AUBRY
Advisor
Advisor

@-didier- Ca m'a tout l'air de profils issus de COVADIS.

Yoan AUBRY

EESignature

0 J'aime
Message 7 sur 13

-didier-
Advisor
Advisor

@Bonjour @Y.AUBRY 

 

Je ne pense pas, justement, Sinon j'aurais renvoyé vers un autre forum, ici on ne traite pas les produits tiers.

Amicalement

Éternel débutant.. my site for learning : Programmer dans AutoCAD

DA

EESignature

0 J'aime
Message 8 sur 13

Y.AUBRY
Advisor
Advisor

Ben ca y ressemble grandement pourtant

 

Exemple de profil issu de Covadis dans notre service RTE

YAUBRY_0-1663919641846.png

 

YAUBRY_1-1663919690558.png

A+ Yoan

Yoan AUBRY

EESignature

0 J'aime
Message 9 sur 13

Y.AUBRY
Advisor
Advisor
Solution acceptée

Bonjour,

 

Je ne suis pas un pro du lisp mais voilà ce que j'ai pu faire.

 

Il faudra bien entendu remplacer "NOM_DU_BLOC" par le nom de ton bloc a insérer

 

Le nom actuelle de la commande est IB_YMIN

 

 

 

;;  IB_YMIN.lsp [command name: IB_YMIN]
;;  Insert des blocs (les blocs doivent être présent dans le fichier
;;  ou dans un des dossiers présents dans les chemins de recherche de fichiers de support
;;  au niveau du Y mini d'une selection
;;  au niveau du X mini et du X Maxi (dans le calque courant)
;;  Yoan AUBRY - 26/09/2022
;; Modification du code SmallestRectangle.lst de Kent Cooper
(defun C:IB_YMIN (/ obb oBG oHD ss BG HD); = IB_YMIN
    (defun obb (ent); = Coins de la boîte englobante de l'objet
    (vla-getboundingbox (vlax-ename->vla-object ent) 'minpt 'maxpt)
    (setq
      oBG (vlax-safearray->list minpt); Position en bas à gauche des objets
      oHD (vlax-safearray->list maxpt); Position en haut à droit des objets
    ); setq
  ); defun -- obb
  (vl-load-com)
  (prompt "\nAjouter de blocs au niveau du Ymin d'une sélection (au xmin et Xmax),")
  (setq ss (ssget))
  (obb (ssname ss 0))
  (setq BG oBG HD oHD); initialisation globale de BG & HD [du premier objet] 
  (ssdel (ssname ss 0) ss)
  (repeat (sslength ss)
    (obb (ssname ss 0))
    (setq
      BG (mapcar 'min oBG BG); Point le plus bas de chacun des objets de la sélection
      HD (mapcar 'max oHD HD); Point le plus haut de chacun des objets de la sélection
    ); setq
    (ssdel (ssname ss 0) ss)
  ); repeat
  (setq 
	MinX (car BG) ; premier élément de la liste (la liste étant les coordonnées d'un point, retourne X au format real)
	MaxX (car HD) ; premier élément de la liste (la liste étant les coordonnées d'un point, retourne X au format real)
	MinY (cadr BG) ; second élément de la liste (la liste étant les coordonnées d'un point, retourne Y au format real)
	sMinX (rtos Minx 2 6) ; convertion de real en string de MinX (le 2 correspond au format décimal, le 6 au nombre de chiffre après la virgule)
	sMaxX (rtos MaxX 2 6) ; convertion de real en string de MaxX
	sMinY (rtos MinY 2 6) ; convertion de real en string de MinY
	MinXMinY (strcat sMinX "," sMinY) ;concaténation de sMinX et sMinY (pour obtenir un point)
	MaxXMinY (strcat sMaxX "," sMinY) ;concaténation de sMaxX et sMinY (pour obtenir un point)
  );sq
  (command "_.insert" "NOM_DU_BLOC" MinXMinY "1" "" "0") ; Insertion du bloc NOM_DU_BLOC au point MinXMinY avec echelle X = 1, Echelle Y = Echelle X, rotation 0
  (command "_.insert" "NOM_DU_BLOC" MaxXMinY "1" "" "0") ; Insertion du bloc NOM_DU_BLOC au point MaxXMinY avec echelle X = 1, Echelle Y = Echelle X, rotation 0
  (princ)
); defun -- C:IB_YMIN

 

 

 

J'espère que ca te conviendra

 

A+ Yoan

Yoan AUBRY

EESignature

0 J'aime
Message 10 sur 13

SET040
Advocate
Advocate

Bonjour @Y.AUBRY,

 

Effectivement, il s'agit d'un profil issu de Covadis mais ce dernier ne permet pas ce type d'habillage. Il faut forcément passer par de l'autolisp.

 

Ensuite, ce n'était qu'un exemple d'utilisation car ce lisp me permettra également à habiller des cartouches de présentation de manière automatisée, etc...  🙂

 

Cela fonctionne à merveille, encore merci à tous les 2 pour votre aide 🙏

0 J'aime
Message 11 sur 13

Luna3
Advocate
Advocate

Coucou,

On peut simplifier en utilisant la fonction (LM:ssBoundingBox) de LeeMac permettant justement de retourner les points bas gauche et haut droit d'un jeu de sélection. Sinon j'ai également pris en compte la possibilité d'existence d'attributs, désactivé les accrochages objets pour éviter les soucis avec (command) et vérifié l'existence du dit bloc dans le dessin, par pure précaution :

(defun c:IB_YMIN (/ *error* LM:ssBoundingBox bins lst val jsel bn ptn ptx)
  (defun *error* (msg)
    (mapcar 'setvar lst val)
    (princ msg)
  )
  (defun LM:ssboundingbox ( sel / idx llp ls1 ls2 obj urp )
    (repeat (setq idx (sslength sel))
      (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))
      (if
        (and
          (vlax-method-applicable-p obj 'getboundingbox)
          (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'llp 'urp))))
        )
        (setq
          ls1 (mapcar 'min (vlax-safearray->list llp) (cond (ls1) ((vlax-safearray->list llp))))
          ls2 (mapcar 'max (vlax-safearray->list urp) (cond (ls2) ((vlax-safearray->list urp))))
        )
      )
    )
    (if (and ls1 ls2) (list ls1 ls2))
  )
  (defun bins (bn pt)
    (command "_-INSERT" bn pt 1 1 0)
    (while (= 1 (getvar "CMDACTIVE"))
      (command "")
    )
    (princ)
  )
  
  (setq
    lst (list "OSMODE" "ATTDIA")
    val (mapcar 'getvar lst)
  )
  (mapcar 'setvar lst '(0 0))
  (if (setq jsel (ssget))
    (progn
      (setq
        bn "NOM_DU_BLOC" ; <-- remplacer par le nom du bloc désiré !!
        pts (LM:ssBoundingBox jsel)
        ptn (car pts)
        ptx (cadr pts)
        ptx (subst (cadr ptn) (cadr ptx) ptx)
      )
      (cond
        ( (tblsearch "BLOCK" bn) bn)
        ( (while (not (tblsearch "BLOCK" bn)) (princ (strcat "\n\"" bn "\" n'est pas un nom valide...")) (setq bn (getstring T "\nEntrer le nom du bloc : "))))
      )
      (bins bn ptn)
      (bins bn ptx)
    )
  )
  (mapcar 'setvar lst val)
  (princ)
)

Si le bloc n'est pas trouvé dans la liste des blocs du dessin, alors il faut renseigner le nom du bloc manuellement (la casse n'est pas prise en compte).

 

Bisous,
Luna

Message 12 sur 13

Y.AUBRY
Advisor
Advisor

Salut Luna,

(de retour parmi nous a ce que je vois)

Merci pour l'update de ma commande qui n'était pas très propre au niveau du code... 😉

A+ Yoan

Yoan AUBRY

EESignature

0 J'aime
Message 13 sur 13

Luna3
Advocate
Advocate
Coucou,
Vui, ce n'est pas toujours évident d'être active sur CADxp et AutoDesk (FR) donc je reviens ici de temps en temps lorsque j'ai un peu de disponibilité ^^
Ne t'en fais pas pour la propreté de ton code, c'était parfaitement fonctionnel 😉 et puis le LISP n'est pas ta langue maternelle.

Bisous,
Luna