Author Topic: coordinates of subentities  (Read 15286 times)

0 Members and 1 Guest are viewing this topic.

csgoh

  • Newt
  • Posts: 176
coordinates of subentities
« on: March 31, 2008, 05:08:00 AM »
I am not familiar with blocks and i hope tp get some help.
How to get the coordinates of the subentities in a block.
i dont mean the insertion point of the block.
asssuming a block has 3 POINTs, a TEXT and a LINE entity. How to extract the coordinates of the 3 POINTS, the insertion point of the TEXT, the start and end point of the line in relation to the WCS.
thanks

csgoh

Bryco

  • Water Moccasin
  • Posts: 1883
Re: coordinates of subentities
« Reply #1 on: March 31, 2008, 10:22:10 AM »
The block itself has the relationship of all the subentities to the insertionpoint.
Applying a matrix to the coordinates of the subentity (the matrix is a combo of the translation reqd. to get to the blockref insertion point , the rotation of the block and the block normal) will give you the point reqd.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: coordinates of subentities
« Reply #2 on: March 31, 2008, 03:28:57 PM »
Hi,

I'm going to try to explain the way I do in spite of my poor English.

First, get the entity using nentsel

nentsel returns a list wich:
1st item is the object ename
2nd item the pick point coordinates (UCS)
3rd item a 4X3 transformation matrix
4th item a list of references enames from the most nested (the entity owner) to the less one.

Code: [Select]
(setq ent (nentsel))
(setq ename (car ent)) ;ename of nested selected entity
(setq owner (car (last ent))) ;ename of the entity owner
(setq mat (reverse (cdr (reverse (caddr ent))))) ; 3X3 tranformation matrix
(setq ins (last (caddr ent))) ; insertion point of the owner
(setq coord (cdr (assoc 10 (entget ename)))) ; entity coordinates in its owner definition

The transformation matrix returned by nentsel can be splited in a 3X3 rotation and scaling matrix and a displacement vector (matrix last row).
The 3X3 matrix corresponds to the transformation from the reference insertion (including rotations and X,Y,Z scalings) to the block definition.
The vector corresponds to the displacement from WCS origin to the insertion point of the owner of selected entity.

So, we can transform the "original" entity coordinates to its "transformed" coordinates in the reference by applaying them the transposed 3X3 matrix and and displace ithem with the displacement vector.

To do this I use 2 little routines mxv and trp.

Code: [Select]
;; transpose une matrice by Doug Wilson
(defun trp (m)
  (apply 'mapcar (cons 'list m))
)

;; Apply a transformation matrix to a vector by Vladimir Nesterovsky
(defun mxv (m v)
  (mapcar (function (lambda (r) (vxv r v))) m)
)

(setq WCScoord (mapcar '+ ins (mxv (trp mat) coord)))

Hope it helps.
« Last Edit: March 31, 2008, 03:33:37 PM by gile »
Speaking English as a French Frog

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: coordinates of subentities
« Reply #3 on: March 31, 2008, 03:40:30 PM »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: coordinates of subentities
« Reply #4 on: March 31, 2008, 04:10:09 PM »
You can also find, here a routine (RCS2WCS) which do the same job:

Code: [Select]
(setq ent (nentsel))
(setq WCScoord (rcs2wcs (cdr (assoc 10 (entget (car ent)))) (caddr ent)))

Speaking English as a French Frog

csgoh

  • Newt
  • Posts: 176
Re: coordinates of subentities
« Reply #5 on: April 01, 2008, 12:16:26 AM »
thanks guys.
will try it out.

csgoh

  • Newt
  • Posts: 176
Re: coordinates of subentities
« Reply #6 on: April 02, 2008, 05:06:14 AM »
codes as suggested by link from gile

Code: [Select]
;;; VXV Returns the dot product of 2 vectors
(defun vxv (v1 v2)
  (apply '+ (mapcar '* v1 v2))
)

;;; VLEN Returns the length of a vector
(defun vlen (v)
  (sqrt (vxv v v))
)

;;; VUNIT Returns the single unit vector of a vector
(defun vunit (v / l)
  (if (/= 0 (setq l (vlen v)))
    (mapcar '(lambda (x) (/ x l)) v)
  )
)

;; transpose a matrix Doug Wilson
(defun trp (m)
  (apply 'mapcar (cons 'list m))
)

;; Apply a transformation matrix to a vector by Vladimir Nesterovsky
(defun mxv (m v)
  (mapcar '(lambda (r) (vxv r v)) m)
)

;; Multiply two matrices by Vladimir Nesterovsky
(defun mxm (m q)
  (mapcar '(lambda (r) (mxv (trp q) r)) m)
)

;; translates coordinates from Reference (block or xref) Coordinate System to WCS
;; Arguments :
;; pt : a point in RCS, got by (cdr (assoc 10 (entget (car (nentsel))))) i.e.
;; mat : a transformation matrix as those returned either by (nentsel) or (nentselp)
(defun RCS2WCS (pt mat)
  (if (= 3 (length (car mat)))
    (mapcar '+ (mxv (trp (butlast mat)) pt) (last mat))
    (mapcar '+
    (mxv (mapcar 'butlast (butlast mat)) pt)
    (butlast (mapcar 'last mat))
    )
  )
)

;; translates coordinates from WCS to Reference (block or xref) Coordinate System
(defun WCS2RCS (pt mat / rs_mat tr_vec)
  (if (= 3 (length (car mat)))
    ;; nentsel matrix
    (setq rs_mat (butlast mat) ; scale/rotation matrix
  tr_vec (last mat) ; translation vector
    )
    ;; nentselp matrix
    (setq rs_mat (trp (mapcar 'butlast (butlast mat))) ; scale/rotation matrix
  tr_vec (butlast (mapcar 'last mat)) ; translation vector
    )
  )
  (mxv
    (mxm (mapcar '(lambda (v) (mapcar '/ v (mapcar 'vlen rs_mat)))
'((1 0 0) (0 1 0) (0 0 1))
)
(mapcar 'vunit rs_mat)
    )
    (mapcar '- pt tr_vec)
  )
)

couldn't find the function butlast?
where can i get it.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: coordinates of subentities
« Reply #7 on: April 02, 2008, 05:14:13 AM »
Oopss !

Code: [Select]
(defun butlast (lst) (reverse (cdr (reverse lst))))
Speaking English as a French Frog

csgoh

  • Newt
  • Posts: 176
Re: coordinates of subentities
« Reply #8 on: April 02, 2008, 05:20:28 AM »
thanks gile

csgoh

  • Newt
  • Posts: 176
Re: coordinates of subentities
« Reply #9 on: April 02, 2008, 06:09:21 AM »
Need help. Where have i gone wrong with my lisp? Function returns wrong coordinates for those neted blocks?
Code: [Select]

(defun c:bit ( / AllCoords-List WCSCoord)
 (defun wg:dxf (code ename)
  (cdr (assoc code (entget ename)))
 ); wg:dxf
;---------------------------------
(defun SSNttList (ss / n l)
  (repeat (setq n (sslength ss))
    (setq l (cons (ssname ss (setq n (1- n))) l))
  )
)
;---------------------------------

;;; VXV Returns the dot product of 2 vectors
(defun vxv (v1 v2)
  (apply '+ (mapcar '* v1 v2))
)

;;; VLEN Returns the length of a vector
(defun vlen (v)
  (sqrt (vxv v v))
)

;;; VUNIT Returns the single unit vector of a vector
(defun vunit (v / l)
  (if (/= 0 (setq l (vlen v)))
    (mapcar '(lambda (x) (/ x l)) v)
  )
)

;; transpose a matrix Doug Wilson
(defun trp (m)
  (apply 'mapcar (cons 'list m))
)

;; Apply a transformation matrix to a vector by Vladimir Nesterovsky
(defun mxv (m v)
  (mapcar '(lambda (r) (vxv r v)) m)
)

;; Multiply two matrices by Vladimir Nesterovsky
(defun mxm (m q)
  (mapcar '(lambda (r) (mxv (trp q) r)) m)
)

 (defun butlast (lst)
   (reverse (cdr (reverse lst)))
 )

;; translates coordinates from Reference (block or xref) Coordinate System to ;;WCS
;; Arguments :
;; pt : a point in RCS, got by (cdr (assoc 10 (entget (car (nentsel))))) i.e.
;; mat : a transformation matrix as those returned either by (nentsel) or ;(nentselp)
(defun RCS2WCS (pt mat)
  (if (= 3 (length (car mat)))
    (mapcar '+ (mxv (trp (butlast mat)) pt) (last mat))
    (mapcar '+
    (mxv (mapcar 'butlast (butlast mat)) pt)
    (butlast (mapcar 'last mat))
    )
  )
)
;-------------------------------------

 (prompt "\nSelect BLOCK objects ")

 (if (and (setq SS (ssget '((0 . "INSERT"))))
          (setq SS (SSNttList SS))
     )
  (progn
   (foreach BLK SS
    (setq ent (nentselp (wg:dxf 10 BLK)))
    (setq mat (reverse (cdr (reverse (caddr ent))))) ; 3x3 transformation matrix
    (setq AllCoords-List '())
    (setq bname (wg:dxf 2 BLK))
    (wg:ListBLK bname)
(print "allcoords-List ")(princ allcoords-list)
 (setq WCScoord (mapcar '(lambda (x) (rcs2wcs x (caddr ent))) AllCoords-List))
(print "wcscoord ")(princ wcscoord)
   );foreach
  )
 );if
(princ)
)

;;
;; Routine extracted from BLOCKINFO by
;; ;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler 
;;;   ab2draft@TampaBay.rr.com
;;
 (defun wg:ListBLK ( bname / BLKNtt NextNtt ent)
  (setq BLKNtt (tblobjname "block" bname))
  (setq NextNtt (wg:dxf -2 BLKNtt))
 (print "nextntt ")(princ (entget nextntt))
 (while NextNtt
   (if (eq (wg:dxf 0 NextNtt) "INSERT") ; other nested block
    (progn
     (wg:LISTBLK (wg:dxf 2 NextNtt))
    )
   );if
   (if (setq NextNtt (entnext (wg:dxf -1 NextNtt)))
    (cond
     ((eq (wg:dxf 0 NextNtt) "POINT")
      (setq AllCoords-List (cons (wg:dxf 10 NextNtt) AllCoords-List ))
     );POINT entity
    );cond
   );if
  );while
 );wg:ListBLK



thanks in advance

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: coordinates of subentities
« Reply #10 on: April 02, 2008, 09:43:54 AM »
Hi,

I cannot understand what you want to do.
wg:ListBLK get coords from the block definition, rcs2wcs is to be used with the coords of an entity in an inserted reference.

Try this little routine on the file you posted.

Code: [Select]
(defun c:test (/ os ent pt)
  (setq os (getvar "OSMODE"))
  (setvar "OSMODE" 73)

  ;; get a point
  (setq
    pt (getpoint
"\nPick on a point, a text insertion point or a line start point: "
       )
  )

  ;; get the nested entity
  (setq ent (nentsel "\nSelect the nested entity: "))

  ;; compare coordinates
  (alert
    (strcat
      "Picked point:\t"
      (vl-princ-to-string (trans pt 1 0))
      "\nRCS2WCS return:\t"
      (vl-princ-to-string
(rcs2wcs (cdr (assoc 10 (entget (car ent)))) (caddr ent))
      )
    )
  )
  (setvar "OSMODE" 73)
  (princ)
)[code]
[/code]
« Last Edit: April 02, 2008, 09:58:24 AM by gile »
Speaking English as a French Frog

csgoh

  • Newt
  • Posts: 176
Re: coordinates of subentities
« Reply #11 on: April 03, 2008, 03:45:19 AM »
sorry for the confusion. Like i said i am no good at blocks.

what i  am trying is to get all the wcs coordinates of points, endpoint of lines , text iinsertion pt in a block.

gile, the code you posted is for each selection one at a time.
what about if i select all the blocks at one go, then i need to iterate in order to find what the entities are in the blocks. this is the area where i need help.


Joe Burke

  • Guest
Re: coordinates of subentities
« Reply #12 on: April 03, 2008, 10:38:21 AM »
sorry for the confusion. Like i said i am no good at blocks.

what i  am trying is to get all the wcs coordinates of points, endpoint of lines , text iinsertion pt in a block.

gile, the code you posted is for each selection one at a time.
what about if i select all the blocks at one go, then i need to iterate in order to find what the entities are in the blocks. this is the area where i need help.



AFAIK, there is no way to do what you are asking for.

csgoh

  • Newt
  • Posts: 176
Re: coordinates of subentities
« Reply #13 on: April 04, 2008, 01:09:44 AM »
so, any alternative or workaround.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: coordinates of subentities
« Reply #14 on: April 04, 2008, 11:06:53 AM »
so, any alternative or workaround.

Maybe if you tell us what the finished product would be, then maybe someone knows of a way to do what you want to do.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.