Aller au contenu

Messages recommandés

Posté(e)

Bonjour

 

Cela fait un moment que je bloque dessus.

 

Je suis dans une présentation et je choisis un élément en espace objet (par exemple un Mtext)

(setq val (vlax-ename->vla-object (car (entsel))))

Je vais en espace papier et je sélectionne la fenêtre où s'affiche mon élément sélectionné

(setq fen (vlax-ename->vla-object (car (entsel))))

Maintenant, si j'utilise cette formule, je trouve les coordonnées en espace papier de mon élément sélectionné.

(trans (trans (vlax-get val 'insertionpoint) (vlax-vla-object->ename val) (vlax-vla-object->ename fen)) 2 3)

Tout fonctionne. :)

 

Maintenant, si je sélectionne dans l'espace objet par exemple un Mtext appartenant à un xref

(setq val (vlax-ename->vla-object (car (nentsel))))

Et ben un

(trans (vlax-get val 'insertionpoint) (vlax-vla-object->ename val) (vlax-vla-object->ename fen))

me retourne nil :o

 

ps : je n'ai qu'un scu général, même pour le xref dont son point d'insertion est 0,0,0 et le facteur d'échelle est à 1 (pour faire au plus simple pour l'instant)

 

@+

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

Posté(e)

Salut,

 

Tu ne devrait pas avoir besoin de faire :

(trans (vlax-get val 'insertionpoint) (vlax-vla-object->ename val) (vlax-vla-object->ename fen)) 

 

Si la fenêtre est active, l'expression suivante suffit et fonctionne pour les objets à l'intérieur d'une xref insérée en 0,0 sans rotation ni changement d'échelle.

(trans (trans (vlax-get val 'insertionpoint) 0 2) 2 3) 

 

Si la xref n'est pas insérée en 0,0 et/ou rotation 0 et/ ou échelle 1 il faut utiliser les matrices et vecteurs, j'ai fait, il y a peu un truc pour les blocs imbriqués sur TheSwamp, je peux essayer de l'adapter aux xref...

 

[Edité le 16/4/2008 par (gile)]

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

Posté(e)

Salut (gile)

 

Merci de ta réponse

 

(trans (trans (vlax-get val 'insertionpoint) 0 2) 2 3)

Cela ne fonctionne pas toujours, car si ta fenêtre ne prend qu'une toute petite partie du dessin, la valeur retournée est fausse, d'où l'intérêt d'inclure la fenêtre dans le trans

 

 

Si la xref n'est pas insérée en 0,0 et/ou rotation 0 et/ ou échelle 1 il faut utiliser les matrices et vecteurs, j'ai fait, il y a peu un truc pour les blocs imbriqués sur TheSwamp, je peux essayer de l'adapter aux xref...

Ah oui, je suis preneur, car la prochaine étape est de voir l'échelle du xref, les unités, son insertion et le scu par rapport au sgc.

 

Merci

 

@+

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

Posté(e)

Re,

 

Erratum pour le trans

(trans (trans (vlax-get val 'insertionpoint) 0 2) 2 3)

Fonctionne très bien. Il faut juste faire attention sur quelle fênetre il agit (variable cvport), car si on ne fait pas gaffe et que l'objet sélectionné apparait dans plusieurs fenêtres, on a vite fait de se planter.

 

@+

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

Posté(e)

Quelques routines et lignes de codes pour retourner le point d'origine (DXF 10) dans le SCG d'une entité imbriquée dans des blocs et/ou des xrefs (ça semble marcher quelque soit le niveau d'imbrication).

 

;; transpose une matrice -Doug Wilson-
(defun trp (m)
 (apply 'mapcar (cons 'list m))
)

;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky-
(defun mxv (m v)
 (mapcar (function (lambda (r) (apply '+ (mapcar '* r v))))
  m
 )
)

(setq nent (nentsel))
(setq mat (reverse (cdr (reverse (caddr nent))))) ; matrice 3X3
(setq ins (last (caddr nent)))
(setq pt (mapcar '+ (mxv (trp mat) (cdr (assoc 10 (entget (car nent))))) ins))

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

Posté(e)

Re,

 

Merci (gile)

Ca marche super bien avec nentsel :)

Maintenant, je n'arrive pas à adapter ton lisp pour me passer de nentsel et d'utiliser directement un objet vla à la place

 

@+

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

Posté(e)

Ben oui, le gros avantage avec nentsel c'est que cette fonction retourne une matrice qui décrit toutes les transformations subies par l'objet à chaque imbrication.

En partant de l'objet "nu" il va falloir transformer son point d'insertion en fonction des transformations de chacun des objets "propriétaires" jusqu'à l'espace objet...

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

Posté(e)

J'ai un peu de mal à trouver quelque chose en partant d'un objet imbriqué, je trouve facilement la définition du parent (owner), mais il faudrait la référence à laquelle il appartient pour récupérer les éventuelles transformations et ceci à chaque niveau d'imbrication.

C'était plus facile dans l'autre sens : partant de "l'ancêtre" retrouver toute la descendance. C'est ce que j'avais fait sur TheSwamp, je t'en donne une adaptation qui cherche tous les points d'insertion dans le SCG des textes, mtextes et attributs contenus dans la ou les références sélectionnées. Si ça peut aider...

 

EDIT RefGeom ne fonctionnait pas si le point de base du bloc était différent de 0,0,0.

 

;; RefGeom
;; Retourne une liste dont le premier élément est une matrice de transformation
;; (rotation, échelles, mormale) de dimension 3X3 et le second le point
;; d'insertion de l'objet dans son "parent" (xref, bloc ou espace)
(defun RefGeom (ename / elst ang norm mat)
 (setq	elst (entget ename)
ang  (cdr (assoc 50 elst))
norm (cdr (assoc 210 elst))
 )
 (list
   (setq mat
   (mxm
     (mapcar (function (lambda (v) (trans v 0 norm T)))
	     '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
     )
     (mxm
       (list (list (cos ang) (- (sin ang)) 0.0)
	     (list (sin ang) (cos ang) 0.0)
	     '(0.0 0.0 1.0)
       )
       (list (list (cdr (assoc 41 elst)) 0.0 0.0)
	     (list 0.0 (cdr (assoc 42 elst)) 0.0)
	     (list 0.0 0.0 (cdr (assoc 43 elst)))
       )
     )
   )
   )
   (trans
     (mapcar
'-
(cdr (assoc 10 elst))
(mxv mat
     (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 elst)))))
)
     )
     norm
     0
   )
 )
)
;; Blk2Coord
;; Retourne une liste des coordonnées SCG des textes, mtextes et attributs
;; contenus dans une référence (xref ou bloc) et affiche dans la fenêtre de texte
;; les niveaux d'imbrication
(defun Blk2Coord (ref mat ins tab / name blk ent elst typ lst)
 (setq	name (cdr (assoc 2 (entget ref)))
blk (tblsearch "BLOCK" name)
ent (cdr (assoc -2 blk))
 )
 (princ (strcat tab "\"" name "\"\n"))
 (setq tab (strcat "   " tab))
 (while ent
   (setq elst (entget ent)
  typ  (cdr (assoc 0 elst))
   )
   (cond
     ((member typ '("MTEXT" "TEXT"))
      (setq lst (cons (mapcar '+ ins (mxv mat (cdr (assoc 10 elst)))) lst))
      (princ
 (strcat tab typ (vl-princ-to-string (car lst)) "\n")
      )
     )
     ((= typ "ATTDEF")
      (setq lst (cons (mapcar '+ ins (mxv mat (cdr (assoc 10 elst)))) lst))
      (princ
 (strcat tab "ATTRIB" (vl-princ-to-string (car lst)) "\n")
      )
     )
     ((= "INSERT" typ)
(setq nent (RefGeom ent)
      lst  (append
	     (Blk2Coord	ent
			(mxm mat (car nent))
			(mapcar '+ ins (mxv mat (cadr nent)))
			tab
	     )
	     lst
	   )
)
     )
     (T nil)
   )
   (setq ent (entnext ent))
 )
 lst
)

;; Transpose une matrice -Doug Wilson-
(defun trp (m)
 (apply 'mapcar (cons 'list m))
)

;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky-
(defun mxv (m v)
 (mapcar (function (lambda (r) (apply '+ (mapcar '* r v))))
  m
 )
)

;; Multiplie deux matrices -Vladimir Nesterovsky-
(defun mxm (m q)
 (mapcar (function (lambda (r) (mxv (trp q) r))) m)
)

;; Fonction de test

(defun c:test (/ ss n ent mtx lst)
 (if (setq ss (ssget '((0 . "INSERT"))))
   (repeat (setq n (sslength ss))
     (terpri)
     (setq ent	(ssname ss (setq n (1- n)))
    mtx	(RefGeom ent)
    lst	(cons (Blk2Coord ent (car mtx) (cadr mtx) "- ") lst)
     )
   )
 )
 (mapcar 'print (reverse (mapcar 'reverse lst)))
 (textscr)
 (princ)
) 

[Edité le 16/4/2008 par (gile)]

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

Posté(e)

Salut,

 

La routine que je donnais fonctionne avec les blocs comme avec les xrefs, mais dans l'autre sens.

Tu lances "test" et tu sélectionnes la xref, elle retourne les points d'insertion de tous les textes et attributs contenus dans la xref et les blocs et xrefs imbriqués dans celle-ci.

Exemple :

- "Xref2" contient Xref1, un bloc "bloc" et un texte

- "Xref1" contient 2 occurences du bloc "bloc", un texte et 2 occurrence du bloc "bloc-imb"

- "bloc_imb" contient les blocs "bloc" et "bloc-att"

- "bloc-att" contient deux attributs

-"bloc" contient 1 texte

 

Commande: test

 

Choix des objets: 1 trouvé(s)

 

Choix des objets:

 

- "Xref2"

---- "Xref1"

------ "Xref1|bloc"

-------- TEXT(141.653 213.751 43.6538)

------ "Xref1|bloc"

-------- TEXT(33.7578 119.881 37.3603)

------ TEXT(50.1699 74.3557 34.3081)

------ "Xref1|bloc-imb"

-------- "Xref1|bloc"

---------- TEXT(172.465 148.099 39.2522)

-------- "Xref1|bloc-att"

---------- ATTRIB(166.256 162.277 40.2027)

---------- ATTRIB(169.859 157.831 39.9047)

------ "Xref1|bloc-imb"

-------- "Xref1|bloc"

---------- TEXT(12.8629 140.474 112.333)

-------- "Xref1|bloc-att"

---------- ATTRIB(-2.00812 145.314 120.316)

---------- ATTRIB(4.37849 144.295 118.006)

---- "Xref2|bloc"

------ TEXT(149.743 54.6007 0.0)

---- TEXT(124.0 85.8672 0.0)

 

((141.653 213.751 43.6538) (33.7578 119.881 37.3603) (50.1699 74.3557 34.3081)

(172.465 148.099 39.2522) (166.256 162.277 40.2027) (169.859 157.831 39.9047)

(12.8629 140.474 112.333) (-2.00812 145.314 120.316) (4.37849 144.295 118.006)

(149.743 54.6007 0.0) (124.0 85.8672 0.0))

 

Ta version de ObjMatrix de Joe Burke n'est pas la dernière (voir ici).

Sa routine TransPt requiert comme argument la liste des entités "parent" (comme le dernier élément des listes retournées par nentsel ou nenselp) or je pensais que tu voulais partir avec uniquement une entité graphique (ename ou vla-object).

 

J'ai essayé en récupérant la liste de tous points d'insertion des objets du même type de retrouver ensuite l'objet initial avec nentselp mais j'ai un problème avec les objets contenus dans des blocs insérés dans les xrefs : ils ont tous les mêmes ename et handle, impossible de les différencier.

 

Si en plus, du ename ou vla-object de l'entité on a accès à ceux de tous les parents, ça ne devrait pas poser de problème (comme avec TransPt).

 

[Edité le 17/4/2008 par (gile)]

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

Posté(e)

Re

 

Oui, mais tu parcours les blocs dans le dessin courant, alors que moi, je parcours le xref avec ObjectDbx si nécessaire.

Désolé si je n'ai pas été assez précis, mais ce que tu donnes n'est pas perdu ;)

Donc, je fais une routine qui recherche une chaîne de texte un peu comme la commande _find (un peu trop sommaire à mon goût, car la boite de dialogue est toujours présente, il ne sait pas gérer les différents scu, les calques gelés, etc...), puis zoom dessus. Donc, je scrute le dessin, les xrefs, etc...

Le texte peut être du type text, mtext, dans des attributs, etc...

Voici le lisp pas tout à fait finalisé. Il me reste à résoudre (et je pense avoir trouvé) quand une fenêtre ne prend pas tout le dessin, que le texte est visible dans la fenêtre et que les coordonnées qui me sont donnée par un (trans obj 2 3) sortent de cette fenêtre.

 

@+

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

Posté(e)

Intéressant ;)

 

Sans vouloir me mettre en avant, j'avais fait RCS2WCS et WCS2RCS qui font la même chose que TransPt à ceci près que l'argument est une matrice au lieu d'une liste de enames.

 

J'ai adapté ça pour en faire quelque chose de plus proche de TransPt, si tu veux un peu alléger ta routine...

 

EDIT : prise en compte des points de base différents de 0,0,0

 

;; TransNested
;; Convertit les coordonnées d'un point entre le SCG ou le SCU  et le SCR -systéme de
;; coordonées d'une référence (xref ou bloc) quelque soit son niveau d'imbrication-
;;
;; Arguments
;; pt : le point à convertir
;; rlst : la liste des entités "parents" de la plus imbriqué à celle insérée dans
;;        l'espace courant -indentique à (last (nentsel)) ou (last (nentselp))
;; from to : comme avec trans : 0 pour le SCG, 1 pour le SCU courant, 2 pour le SCR
;;              (avec 1 et 0 le résultat est le même qu'avec la fonction trans)

(defun TransNested (pt rlst from to / mat dep)
 (setq mat '((1 0 0) (0 1 0) (0 0 1)))
 (and (= 1 from) (setq pt (trans pt 1 0)))
 (and (= 2 to) (setq rlst (reverse rlst)))
 (and (or (= 2 from) (= 2 to))
      (while rlst
 (setq geom (if	(= 2 to)
	      (RevRefGeom (car rlst))
	      (RefGeom (car rlst))
	    )
       rlst (cdr rlst)
       mat  (mxm (car geom) mat)
       pt   (mapcar '+ (mxv (car geom) pt) (cadr geom))
 )
      )
 )
 (if (= 1 to)
   (trans pt 0 1)
   pt
 )
)

;; RefGeom
;; Retourne une liste dont le premier élément est une matrice de transformation
;; (rotation, échelles, mormale) de dimension 3X3 et le second le point
;; d'insertion de l'objet dans son "parent" (xref, bloc ou espace)

(defun RefGeom (ename / elst ang norm mat)
 (setq	elst (entget ename)
ang  (cdr (assoc 50 elst))
norm (cdr (assoc 210 elst))
 )
 (list
   (setq mat
   (mxm
     (mapcar (function (lambda (v) (trans v 0 norm T)))
	     '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
     )
     (mxm
       (list (list (cos ang) (- (sin ang)) 0.0)
	     (list (sin ang) (cos ang) 0.0)
	     '(0.0 0.0 1.0)
       )
       (list (list (cdr (assoc 41 elst)) 0.0 0.0)
	     (list 0.0 (cdr (assoc 42 elst)) 0.0)
	     (list 0.0 0.0 (cdr (assoc 43 elst)))
       )
     )
   )
   )
   (trans
     (mapcar
'-
(cdr (assoc 10 elst))
(mxv mat
     (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 elst)))))
)
     )
     norm
     0
   )
 )
)

;; RevRefGeom
;; Fonction inverse de RefGeom
(defun RevRefGeom (ename / entData ang norm mat)
 (setq	entData	(entget ename)
ang	(- (cdr (assoc 50 entData)))
norm	(cdr (assoc 210 entData))
 )
 (list
   (setq mat
   (mxm
     (list (list (/ 1 (cdr (assoc 41 entData))) 0.0 0.0)
	   (list 0.0 (/ 1 (cdr (assoc 42 entData))) 0.0)
	   (list 0.0 0.0 (/ 1 (cdr (assoc 43 entData))))
     )
     (mxm
       (list (list (cos ang) (- (sin ang)) 0.0)
	     (list (sin ang) (cos ang) 0.0)
	     '(0.0 0.0 1.0)
       )
       (mapcar (function (lambda (v) (trans v norm 0 T)))
	       '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
       )
     )
   )
   )
   (mapcar '-
    (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 entData)))))
    (mxv mat (trans (cdr (assoc 10 entData)) norm 0))
   )
 )
)

;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky-
(defun mxv (m v)
(mapcar (function (lambda (r) (apply '+ (mapcar '* r v))))
m
)
)

;; Multiplie deux matrices -Vladimir Nesterovsky-
(defun mxm (m q)
(mapcar (function (lambda (r) (mxv (trp q) r))) m)
) 

[Edité le 17/4/2008 par (gile)]

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

Posté(e)

Merci (gile)

 

Sans vouloir me mettre en avant
Je sais que ce n'est pas l'habitude de la maison ;)

 

J'adopte ton lisp.

 

Il faut dire que j'ai du mal avec les matrices. Je pense comprendre à quoi elles servent, mais n'ayant pas les bases en math, dur dur de s'y mettre.

J'ai aussi compris qu'il va falloir encore utiliser une matrice pour un viewport. Pas simple, mais je m'y attèle.

Pour info, je pense qu'il s'agit du code 1010 dans les xdatas.

 

@+

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

Posté(e)

Salut,

 

Je ne suis pas vraiment très pointu avec les matrices, je m'y suis mis il y a peu et continue à essayer d'apprendre.

 

Un tuto assez clair su les matrices de transformation ici, ils utilisent les matrices 4X4 (comme Joe Burke), de mon côté je préfère utiliser des matrices 3X3 pour les rotations , échelles (et normale en 3d) et traiter les déplacements à part avec (mapcar '+ ...)

 

Avec les routines trp, mxm, imxv, il est assez aisé de transposer, combiner et appliquer des matrices à des vecteurs (ce qui revient à convertir un point).

 

J'ai posté ici une nouvelle routine qui retourne la matrice inverse d'une matrice de changement d'échelle (s'il n'y a pas de changement d'échelle trp retourne la matrice inverse).

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

Posté(e)
coucou

 

c'est t'y pas mignon cà ?

 

le (Gile) nous dit qu'il n'est pas très pointu avec les matrices !!!

 

c'est vrai qu'il n'est guère plus affuté qu'une lame de rasoir neuve

alors hein !!!!

 

t'es trop fort :)

 

amicalement

 

Je ne pensais pas faire de la fausse modestie, à chaque fois que je me replonge dans les problèmes de matrices, je m'aperçois du peu que je sais et des erreurs que j'ai pu faire (par exemple la routine WCS2RCS ne fonctionnait pas avec des transformation multiples)

 

Mais c'est vrai qu'on est assez peu nombreux à jouer avec les matrices ici, alors c'est facile d'apparaître comme un "cador". Mais je m'affute petit à petit, je pense avoir réussi à implémenter l'inversion d'une matrice de transformation avec des échelles différentes (voir ici)

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

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é