Jump to content

How to access entities within an INSERT


jbreard

Recommended Posts

Hello everyone,

 

The subject must have been already discussed somewhere here but I can't seem to find it.

 

For a routine I'm writing, I must access the LWPOLYLINE entities constituting INSERTS and their coordinates. Now I have understand how to access the entities in a block via the entnext method. The same method give me some results on a particular INSERT but nothing that makes much sense.

 

Would you know how to access the entities within an INSERT given that I want there exact position as it lays on the drawing ?

 

Thanks a lot,

 

Jacques

Link to comment
Share on other sites

Your looking for plines in a block, is the block 1 pline ? Then explode get pline vertices then UNDO.

 

Nentsel may work pick pline. 

(setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (car (nentsel "pick pline"))))))
 

Link to comment
Share on other sites

Thans Bigal for your response,

 

I don't want to explode my block instance (INSERT) unless I have a way to do it with LISP. I should explain my problematic a bit more.

 

I have writtent a programm that generates cross sections of a railway tunnel from a topographic scan survey. The programm insert in each cross section particular blocks that represent the gauge of the rolling stock. So for each cross section, I have blocks instances which are different (but which I can retrieve by name) and which have all a particular rotation (depending on the track geometry). What I want to achieve in the end is check for conflicts between the gauge and the tunnel and for that I must access the plines part of the gauge blocks to look for 2D-plines intersection between the plines of the tunnel and those from the gauge.

 

My problem is that I can retrieves thoses plines in the block definition (entnext on the block entity and then a while with a filter for LWPOLYLINE) but then they will always have the same coordinates as the block definition. What I need is access them in the particular configuration of th inserted block instance.

 

If you have an idea or if I did not understand what you proposed on your first post and you can explain it a bit more I would be grateful.

 

Thanks,

 

Jacques

 

 

Link to comment
Share on other sites

you probably need something like the in de code below but I'm not very good with matrixes, have written some apps that deal with them but as soon as I fished them my mind went blank again 🤪

 


; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/get-entities-inside-a-block/td-p/2644829
; Entmatrix returns a list which first item is the 3X3 tranformation matrix and second item
; the insertion point of a block refernce in its owner (space or block definition)
(defun EntMatrix (ename / elst ang norm)
  (setq elst (entget ename)
 ang  (cdr (assoc 50 elst))
 norm (cdr (assoc 210 elst))
  )
  (list
    (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 (cdr (assoc 10 elst)) norm 0)
  )
)

;; Blk2Coord
;; Returns a list of a block reference entities coordinates
(defun Blk2Coord (ref mat ins / blk ent lst)
  (setq blk (tblsearch "BLOCK" (cdr (assoc 2 (entget ref)))))
  (setq ent (cdr (assoc -2 blk)))
  (while ent
    (setq elst (entget ent)
   typ  (cdr (assoc 0 elst))
    )
    (cond
      ((= "LINE" typ)
       (setq lst (cons (list typ
        (mapcar '+ ins (mxv mat (cdr (assoc 10 elst))))
        (mapcar '+ ins (mxv mat (cdr (assoc 11 elst))))
         )
         lst
   )
       )
      )
      ((member typ '("POINT" "TEXT"))
       (setq lst (cons (list typ
        (mapcar '+ ins (mxv mat (cdr (assoc 10 elst))))
         )
         lst
   )
       )
      )
      ((= "INSERT" typ)
       (setq nent (EntMatrix ent))
       (setq lst
       (append
  lst
  (Blk2Coord ent
      (mxm  mat (car nent))
      (mapcar '+ ins (mxv mat (cadr nent)))
  )
       )
       )
      )
      (T nil)
    )
    (setq ent (entnext ent))
  )
  (cons (list (cdr (assoc 2 blk)) ins) lst)
)

;; 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 (function (lambda (r) (apply '+ (mapcar '* r v))))
   m
  )
)

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

;; Main function

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

(c:test)

Link to comment
Share on other sites

3 hours ago, jbreard said:

Thans Bigal for your response,

 

I don't want to explode my block instance (INSERT) unless I have a way to do it with LISP. I should explain my problematic a bit more.

 

I have writtent a programm that generates cross sections of a railway tunnel from a topographic scan survey. The programm insert in each cross section particular blocks that represent the gauge of the rolling stock. So for each cross section, I have blocks instances which are different (but which I can retrieve by name) and which have all a particular rotation (depending on the track geometry). What I want to achieve in the end is check for conflicts between the gauge and the tunnel and for that I must access the plines part of the gauge blocks to look for 2D-plines intersection between the plines of the tunnel and those from the gauge.

 

My problem is that I can retrieves thoses plines in the block definition (entnext on the block entity and then a while with a filter for LWPOLYLINE) but then they will always have the same coordinates as the block definition. What I need is access them in the particular configuration of th inserted block instance.

 

If you have an idea or if I did not understand what you proposed on your first post and you can explain it a bit more I would be grateful.

 

Thanks,

 

Jacques

 

 

 

Copy the block using the (vla-copy) method

Explode the copy using (vla-explode) method. This returns a list of block entities if yo 

Sift the list deleting all but the polylines

Do your comparisons

Erase the exploded polylines left in the list

 

(setq obj (vlax-ename->vla-object (car (entsel)))) => Select object: #<VLA-OBJECT IAcadBlockReference2 0000000028d7a668>

(setq n_obj (vla-copy obj)) => #<VLA-OBJECT IAcadBlockReference2 0000000028c87238>

(setq e_lst (vlax-invoke n_obj 'explode)) => (#<VLA-OBJECT IAcadLine2 00000000289ba048> #<VLA-OBJECT IAcadHatch2 00000000289badc8> #<VLA-OBJECT IAcadCircle2 00000000289bab88>)

(vla-delete n_obj)

The copy is belt and braces and is on top of the original object. The explode does not destroy the original copied object..

The delete deletes the copied object.

 

e_lst contains the list of objects that were in the copied block. This can be iterated to obtain whatever you want and compared to whatever you want. They should be delete when finished

Link to comment
Share on other sites

Thanks dlanor and rlx,

 

I think I will try first the explode method to avoid the matrix (me too I tend to forget quickly about them :)

 

I will tell you how it went.

 

Thanks again,

 

Jacques

Link to comment
Share on other sites

I totally agree that the simplest (in this case explode) solution often is the best solution. Sure matrixes are fast and by themselves they are not rocket science but you just have to use them regularly to be able to feel comfortable enough to use them. Its a little like the 🐔 and the 🍳 / use it or lose it... good luck with your app :thumbsup:

Edited by rlx
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...