Aller au contenu

insérer un bloc


zebulon_

Messages recommandés

bonjour,

 

j'ai fait ceci pour insérer un bloc

 

 
(defun insert_block (NOM PT ECHX ECHY ECHZ ROT / AcDoc SPACE REF LATT UCSZDIR Util)
 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
 (setq Util (vla-get-utility AcDoc))
 (setq UCSZDIR (trans '(0 0 1) 1 0 T))
 (setq ROT (+ ROT (vla-AngleFromXAxis util (vlax-3d-point '(0 0 0)) (vlax-3d-point (trans (getvar "UCSXDIR") 0 ucszdir)))))
 (if (zerop (vla-get-ActiveSpace AcDoc))
   (setq SPACE (vla-get-PaperSpace AcDoc))
   (setq SPACE (vla-get-ModelSpace AcDoc))
 )
 (if (or (tblsearch "BLOCK" NOM)
         (findfile NOM)
         (findfile (setq NOM (strcat NOM ".dwg")))
     )
   (progn
     (setq REF
       (vla-InsertBlock
         SPACE
         (vlax-3d-point (trans PT 1 0))
         NOM
         ECHX
         ECHY
         ECHZ
         ROT
       )
     )
   )
   (alert (strcat "Le bloc \"" (vl-string-rigth-trim ".dwg" NOM) "\" est introuvable"))
 )
)

 

mais ça n'a pas l'air de prendre ne compte les unités de blocs. Quand j'insère un bloc externe, je récupère un bloc "sans unité" alors que j'ai créé le bloc en mm. :casstet:

Forcément, si je dois travailler en mètres, je n'ai pas le bon rapport d'échelle.

 

Du coup, je reste avec le bon vieux (command "_insert" ...) qui me fait le bon rapport entre les unités. C'est dommage...

 

Vous avez une idée ?

 

Amicalement

Zébulon_

 

PS : sur autocad 2007

 

 

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

En pompant ce que j'avais fait pour Edit_bloc, à la fin du progn (tu avais prévu ;) ) ajoute :

(scl_upd REF)

 

(defun scl_upd (obj / u_lst i_unt b_unt)
 (and
   (/= 0 (setq i_unt (getvar "INSUNITS")))
   (/=	i_unt
(setq
  b_unt	(vla-get-Units
	  (vla-item
	    (vla-get-Blocks
	      (vla-get-ActiveDocument (vlax-get-acad-object))
	    )
	    (vla-get-EffectiveName obj)
	  )
	)
)
   )
   (setq u_lst	'("Sans unités"	    "Pouces"	      "Pieds"
	  "Miles"	    "Millimètres"     "Centimètres"
	  "Mètres"	    "Kilomètres"      "Micropouces"
	  "Milles"	    "Yards"	      "Angströms"
	  "Nanomètres"	    "Microns"	      "Décimètres"
	  "Décamètres"	    "Hectomètres"     "Gigamètres"
	  "Unités astronomiques"	      "Parsecs"
	 )
   )
   (vla-ScaleEntity
     obj
     (vla-get-InsertionPoint obj)
     (cvunit 1
      (nth b_unt u_lst)
      (nth i_unt u_lst)
     )
   )
 )
) 

 

PS : il me semble qu'on peut faire plus simple pour ROT (sans vla-AnglefromXAxis ni vla-get-Utility) :

 

(setq rot (+ rot
     (angle '(0 0 0) (trans (getvar "UCSXDIR") 0 ucszdir))
  )
) 

 

[Edité le 30/4/2007 par (gile)]

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

Lien vers le commentaire
Partager sur d’autres sites

il me semble qu'on peut faire plus simple pour ROT (sans vla-AnglefromXAxis ni vla-get-Utility) :

c'était juste pour faire plus vlisp

 

En pompant ce que j'avais fait pour Edit_bloc

on ne peut rien te cacher ;)

 

Je m'en vais essayer le scl_upd. J'avais déjà essayé de faire quelque chose comme ça, juste après l'insertion du block( d'où effectivement la présence du progn)

(setq SCALE (vla-get-InsUnitsFactor REF))
(setq INSPT (vla-get-InsertionPoint REF))
(vla-ScaleEntity REF INSPT SCALE)

 

ce qui marche bien lorsque le bloc est déjà défini dans l'entête du fichier avec le bon facteur d'unité (qui se met correctement quand on insère avec _insert). Mais lorsque le bloc est un fichier externe, le vla-insertblock le reconnait comme un bloc "sans unité" alors que l'ai défini en mm. Donc, j'ai peur que le cvunit ne m'avance pas beaucoup et que ça ressemble à un bug.

 

amicalement

 

Zebulon_

 

 

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

Je confirme ma crainte. Je récupère un bloc "sans unités" quand le bloc est un fichier externe alors que ce bloc est défini en mm.

 

Je vais encore essayer de passer par un vla-CopyObjects associé avec un vla-get-blocks en me faisant un seul fichier bibliothèque (genre DesignCenter) qui contient déjà tous mes blocs définis à la bonne unité.

 

je vous tiens au courant

 

amicalement

 

Zebulon_

 

 

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

j'en suis arrivé là :

 

(defun modif_attrib (E ETIQ VALEUR / LATT ATT)
 (if (= (type E) 'ENAME)
   (setq E (vlax-ename->vla-object E))
 )
 (setq LATT (vlax-invoke E 'getAttributes))
 (foreach ATT LATT
   (if (= (vla-get-TagString ATT) ETIQ)
     (vla-put-TextString ATT VALEUR)
   )
 )
)

(defun insert_block (NOM BIBLIO PT ECHX ECHY ECHZ ROT LISTEATT / AcDoc SPACE REF LATT UCSZDIR Util INSPT SCALE Dbx)
 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
 (setq Util (vla-get-utility AcDoc))
 (setq UCSZDIR (trans '(0 0 1) 1 0 T))
 (setq ROT (+ ROT (vla-AngleFromXAxis util (vlax-3d-point '(0 0 0)) (vlax-3d-point (trans (getvar "UCSXDIR") 0 ucszdir)))))
 ;; si le bloc n'existe pas dans le fichier, je le copie à partir d'un fichier bibliothèque
 (if (not (tblsearch "BLOCK" NOM))
   (progn
     (setq BIBLIO (findfile BIBLIO))
     (setq Dbx (ouvrir_dessin_dbx BIBLIO))
     (vla-CopyObjects Dbx 
       (vlax-safearray-fill
         (vlax-make-safearray vlax-vbObject '(0 . 0))
         (list (vla-item (vla-get-blocks Dbx) NOM))  ;; faudrait encore voir si NOM existe dans dbx
       )
      (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
     )
     (vlax-release-object dbx)
   )
 )
 ;; j'insère le bloc toujours à partir du header.
 (if (zerop (vla-get-ActiveSpace AcDoc))
   (setq SPACE (vla-get-PaperSpace AcDoc))
   (setq SPACE (vla-get-ModelSpace AcDoc))
 )
 (setq REF
   (vla-InsertBlock
     SPACE
     (vlax-3d-point (trans PT 1 0))
     NOM
     ECHX
     ECHY
     ECHZ
     ROT
   )
 )
 (setq SCALE (vla-get-InsUnitsFactor REF))
 (setq INSPT (vla-get-InsertionPoint REF))
 (vla-ScaleEntity REF INSPT SCALE)
 ;; mise à jour des attributs
 (foreach LATT LISTEATT
   (modif_attrib REF (car LATT) (cadr LATT))
 )
)

 

ouvrir_dessin_dbx se trouve ici, sinon Gille va me dire que j'ai pompé ;). Encore merci à Patrick_35.

 

(insert_block "TOTO" "BLOCKMM.DWG" '(0 0) 1 1 1 0 nil)

 

s'il y a des attributs à modifier

(insert_block "TOTO" "BLOCKMM.DWG" '(0 0) 1 1 1 0 '(("ETIQUETTE1" "VALEUR1") ("ETIQUETTE2" "VALEUR2")))

 

Il y a encore (vla-item (vla-get-blocks Dbx) NOM) qui renvoie une erreur quand NOM n'existe pas. Je n'ai pas encore étudié les vl-catch-all-error...

 

Amicalement

Zebulon_

 

 

[Edité le 2/5/2007 par zebulon_]

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

Donc, pas du tout avec les vl-catch-all-error puisqu'il suffit de regarder dans la liste de nom de blocs avec un vlax-for...

 

Voilà ce que ça donne.

 

(defun modif_attrib (E ETIQ VALEUR / LATT ATT)
 (if (= (type E) 'ENAME)
   (setq E (vlax-ename->vla-object E))
 )
 (setq LATT (vlax-invoke E 'getAttributes))
 (foreach ATT LATT
   (if (= (strcase (vla-get-TagString ATT)) (strcase ETIQ))
     (vla-put-TextString ATT VALEUR)
   )
 )
)

(defun block_list (F / b bn tl)
 (vlax-for b (vla-get-blocks F)
   (if (= (vla-get-islayout b) :vlax-false)
     (setq tl (cons (strcase (vla-get-name b)) tl))
   )
 )
 (reverse tl)
)

(defun insert_block (NOM BIBLIO PT ECHX ECHY ECHZ ROT LISTEATT / AcDoc SPACE REF LATT UCSZDIR Util INSPT SCALE Dbx RESULT)
 (setq NOM (strcase NOM))
 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
 (setq Util (vla-get-utility AcDoc))
 (setq UCSZDIR (trans '(0 0 1) 1 0 T))
 (setq ROT (+ ROT (vla-AngleFromXAxis util (vlax-3d-point '(0 0 0)) (vlax-3d-point (trans (getvar "UCSXDIR") 0 ucszdir)))))
 ;; si le bloc n'existe pas dans le fichier, je le copie à partir d'un fichier bibliothèque
 (if (not (member NOM (block_list AcDoc)))
   (if (setq BIBLIO (findfile BIBLIO))
     (progn
       (setq Dbx (ouvrir_dessin_dbx BIBLIO))
       (if (member NOM (block_list Dbx))
         (progn
           (vla-CopyObjects Dbx 
             (vlax-safearray-fill
               (vlax-make-safearray vlax-vbObject '(0 . 0))
               (list (vla-item (vla-get-blocks Dbx) NOM))
             )
            (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
           )
           (vlax-release-object dbx)
         )
       )
     )
   )
 )
 ;; j'insère le bloc toujours à partir du header.
 (if (setq RESULT (car (member NOM (block_list AcDoc))))
   (progn
     (if (zerop (vla-get-ActiveSpace AcDoc))
       (setq SPACE (vla-get-PaperSpace AcDoc))
       (setq SPACE (vla-get-ModelSpace AcDoc))
     )
     (setq REF
       (vla-InsertBlock
         SPACE
         (vlax-3d-point (trans PT 1 0))
         NOM
         ECHX
         ECHY
         ECHZ
         ROT
       )
     )
     (setq SCALE (vla-get-InsUnitsFactor REF))
     (setq INSPT (vla-get-InsertionPoint REF))
     (vla-ScaleEntity REF INSPT SCALE)
     ;; mise à jour des attributs
     (foreach LATT LISTEATT
       (modif_attrib REF (car LATT) (cadr LATT))
     )
   )
 )
 ;; renvoie le nom du bloc inséré ou nil si non trouvé
 RESULT
)

 

 

Mais il y a un truc que je n'ai toujours pas pigé : pourquoi faut-il faire le vla-scaleEntity :casstet:

 

Amicalement

Zebulon_

 

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

Gille va me dire que j'ai pompé

 

C'est pas du tout ce que j'ai voulu dire. C'est moi qui ait repompé (et à peine modifié) scl_upd dans Edit_bloc.

 

Sinon, je suis plutôt flatté que tu utilises ucszdir, par exemple ;)

 

[Edité le 3/5/2007 par (gile)]

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

Lien vers le commentaire
Partager sur d’autres sites

C'est moi qui ait repompé

Ah pardon, j'avais mal compris. Comme on en est tous là à repomper à droite à gauche, j'en conclue que c'est encore cette manière qui est la meilleure pour apprendre. j'ai toujours fait comme ça.

 

Je me souviens de mon premier entretien d'embauche, mon patron de l'époque m'a dit :

Quand je te donne un plan à faire, soit tu es un génie et tu inventes, soit le plan sera faux. Comme tu n'es pas un génie, tu prendras un plan déjà fait en exemple et tu essaieras de faire à peu près pareil

 

Sur le coup, je me suis qu'il se fout de moi. Mais, à la longue, je dois reconnaitre qu'il avait raison. ;)

 

Sinon, j'ai remplacé scl_upd par

 

(setq SCALE (vla-get-InsUnitsFactor REF))
(setq INSPT (vla-get-InsertionPoint REF))
(vla-ScaleEntity REF INSPT SCALE) 

 

et là je n'ai pompé sur personne ;)

Cela à l'avantage de ne pas gérer une liste d'unités. InsUnitsFactor se met tout seul à la bonne valeur lors de l'insertion, alors autant en profiter.

 

Exemple : j'ai défini un bloc en mm que j'insère avec vla-insertblock dans un fichier en m, cela donne ceci

 

Commande: (vlax-dump-object e)

; IAcadBlockReference: Interface AutoCAD Block Reference

; Valeurs de propriétés:

; Application (RO) = #

; Document (RO) = #

; EffectiveName (RO) = "FERSYSNOMENC"

; Handle (RO) = "5493"

; HasAttributes (RO) = -1

; HasExtensionDictionary (RO) = 0

; Hyperlinks (RO) = #

; InsertionPoint = (18.1943 -70.0726 0.0)

; InsUnits (RO) = "Millimètres"

[surligneur]; InsUnitsFactor (RO) = 0.001[/surligneur]

; IsDynamicBlock (RO) = 0

; Layer = "NOMENC"

; Linetype = "ByLayer"

; LinetypeScale = 1.0

; Lineweight = -1

; Material = "ByLayer"

; Name = "FERSYSNOMENC"

; Normal = (0.0 0.0 1.0)

; ObjectID (RO) = 2130494488

; ObjectName (RO) = "AcDbBlockReference"

; OwnerID (RO) = 2130377976

; PlotStyleName = "ByLayer"

; Rotation = 0.0

; TrueColor = #

; Visible = -1

[surligneur]; XEffectiveScaleFactor = 1000.0[/surligneur]

; XScaleFactor = 1.0

[surligneur]; YEffectiveScaleFactor = 1000.0[/surligneur]

; YScaleFactor = 1.0

[surligneur]; ZEffectiveScaleFactor = 1000.0[/surligneur]

; ZScaleFactor = 1.0

T

 

ce sont donc ces valeurs 1000.0 qu'il s'agit de mettre à 1000.0*0.001, ce que j'ai fait avec vla-scaleEntity

 

Amicalement

Zebulon_

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

vla-get-InsUnitsFactor est plus court et plus élégant que scl_upd.

 

J'ai repris cette routine par flemme de chercher ;)

Elle utilise la liste d'unités qui était de toutes façons nécessaire pour la boite de dialogue de Edit_bloc.

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

Lien vers le commentaire
Partager sur d’autres sites

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é