Aller au contenu

Position d'un bloc


Fraid

Messages recommandés

Bonjour,

 

Je cherche à faire une fonction qui me donne la position d'un bloc (il n'y en a qu'un dans le dessin)

du genre(PosBloc "Nom du Bloc") qui me retournerai les coordonnées sous forme d'une liste '(0.0 0.0 0.0)

Je sais le faire en Autolisp, mais en VLisp c'est pas évident :blink:

J'ai donc essayé

 

(defun PosBloc (NomBloc / pos)

(setq BLOCS (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))))
(vlax-for Blk BLOCS 
 (if (= NomBloc (vla-get-name Blk))
      (setq pos (gc:3dVariantToPointList (vla-get-Coordinates  Blk )))
  )

)
pos
)

;; gc:3dVariantToPointList (gile)
;; Convertit un variant de coordonnées 3D en liste de points
;; Polyline dans le SCO (Z = 0)
;; 3DFace, 3DPolyline, Leader, MLine, PolyfaceMesh,
;; PolygonMesh, Solid, Trace dans le SCG
;;
;; Argument
;; var : un variant (array de doubles) tel que retourné par vla-get-Coordinates

(defun gc:3dVariantToPointList (var / foo)
 (defun foo (lst)
   (if lst
     (cons (list (car lst) (cadr lst) (caddr lst)) (foo (cdddr lst)))
   )
 )
 (foo (vlax-safearray->list (vlax-variant-value var)))
)

 

j'ai essayé avec (vlax-get blk 'insertionpoint), ce n'est pas mieux

Surement un truc que j'ai loupé... :rolleyes:

Merci

Lien vers le commentaire
Partager sur d’autres sites

On dirait que tu confonds la collection avec les insertions !

(vla-get-Blocks donne la collection et on dirait que tu es parti pour chercher le point de définition.

 

Mais pour trouver des instances de blocs, c'est l'espace objet (je supppose) qu'il faut explorer ;)

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Lien vers le commentaire
Partager sur d’autres sites

Salut

 

(and (setq mon_bloc "MON_BLOC") ; Définir le nom du bloc
    (ssget "x" (list (cons 0 "insert") (cons 2 mon_bloc))) ; Faire une sélection dans le dessin
    (setq mon_bloc (vla-item (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))) 0)) ; Récupére dans le jeu de sélection le 1er bloc
 (vlax-get mon_bloc 'insertionpoint) ; le point d'insertion du 1er bloc
)

 

Que ce soit du lisp ou du vlisp, la logique reste la même.

Sélection dans le dessin puis on prends le 1er élément du jeu de sélection.

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Quand Tramber dit "la collection" il parle de la 'table' des blocs (la collection des définitions de blocs), cette collection ne contient pas de références de blocs, uniquement les définitions.

 

Les références de blocs sont insérées dans des espaces objet ou papier ou encore dans d'autres définitions de bloc.

 

Pour ta demande, si tu ne veux pas utiliser ssget, il faut, comme le disait Tramber, parcourir tout l'espace dans lequel tu cherches ton bloc, ça ne devrait pas être beaucoup plus couteux en temps qu'un (ssget "_x") même avec un filtre qui procède de la même façon (en tout cas ça ne l'est pas en .NET).

 

(defun PosBloc (nom)
 (vl-load-com)
 (vlax-for obj	(vla-get-modelSpace
	  (vla-get-ActiveDocument (vlax-get-acad-object))
	)
   (if
     (and
(= (vla-get-ObjectName obj) "AcDbBlockReference")
(= (vla-get-Effectivename obj) nom)
     )
      (vlax-safearray->list
 (vlax-variant-value
   (vla-get-InsertionPoint obj)
 )
      )
   )
 )
)

 

Une astuce pour éviter le (vlax-safearray->list (vlax-variant-value ..)) consite à utiliser (vlax-get ...) :

 

(defun PosBloc (nom)
 (vl-load-com)
 (vlax-for obj	(vla-get-modelSpace
	  (vla-get-ActiveDocument (vlax-get-acad-object))
	)
   (if
     (and
(= (vla-get-ObjectName obj) "AcDbBlockReference")
(= (vla-get-Effectivename obj) nom)
     )
      (vlax-get obj 'InsertionPoint)
   )
 )
)

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

Lien vers le commentaire
Partager sur d’autres sites

Ce qui est dommage, c'est qu'en LISP il n'existe pas de fonction pour quitter une boucle vlax-for ou foreach avant d'avoir parcouru toute la collection (comme ça existe dans d'autres langages), dans ton cas, dès que le bloc aurait été trouvé, ce qui oblige à continuer à parcourir tout l'espace objet même si le bloc été trouvé (encore une fois, c'est aussi ce que fait (ssget "_X" ...)).

 

Toutefois, on peut faire un équivalent de 'break' en utilisant (while ...) et une variable booléenne (T ou nil) qui fait sortir de la boucle dès que l'élément est trouvé.

 

La routine suivante devrait être plus rapide si le bloc recherché n'est pas le dernier objet ajouté à l'espace objet.

 

(defun PosBloc (nom / ms cnt n break obj insPt)
 (vl-load-com)
 (setq	ms  (vla-get-modelSpace
      (vla-get-ActiveDocument (vlax-get-acad-object))
    )
cnt (vla-get-Count ms)
n   0
 )
 (while (and (not break) (< n cnt))
   (setq obj (vla-Item ms n))
   (if
     (and
(= (vla-get-ObjectName obj) "AcDbBlockReference")
(= (vla-get-Effectivename obj) nom)
     )
      (setq break T
     insPt (vlax-get obj 'InsertionPoint)
      )
     (setq n (1+ n))
   )
 )
 insPt
)

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

Lien vers le commentaire
Partager sur d’autres sites

La routine suivante devrait être plus rapide si le bloc recherché n'est pas le dernier objet ajouté à l'espace objet.
Tu le dis bien !

N'y-a-t-il pas, dans le maintien ou des données étendues, des infos sur l'ancienneté qui permettent de perfectionner une telle routine ?

De sorte que la routine sache, avant d'attaquer si c'est au début ou à la fin de la "collection" !

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Lien vers le commentaire
Partager sur d’autres sites

Un peu hors sujet puisque Fraid voulait le faire en vlisp, mais à mon avis le plus rapide est d'utiliser la routine gc:GetReferences définie ici qui ne parcourt pas le dessin mais accède directement aux références insérées d'une définition de bloc.

 

(defun posbloc (name / refs)
 (if (setq refs (gc:GetReferences name 2))
   (cdr (assoc 10 (entget (car refs))))
 )
)

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

Lien vers le commentaire
Partager sur d’autres sites

Salut

 

Si on veux aller plus vite dans la recherche d'un bloc dans la table, on peut utiliser tout simplement vla-item avec une gestion des erreurs s'il n'existe pas (cela revient à utiliser tblsearch en lisp)

 

Sans la gestion des erreurs

(vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) "MON_BLOC")

 

Avec la gestion des erreurs

(vl-catch-all-apply 'vla-item (list (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) "MON_BLOC"))

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

  • 6 mois aprè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 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é