get the name of the block that the entity is in

get the name of the block that the entity is in

Anonymous
Not applicable
1,965 Views
21 Replies
Message 1 of 22

get the name of the block that the entity is in

Anonymous
Not applicable

there is probably a native function for this but I am not aware, I would like to click on an internal point inside a block and it returns the entname of the block outside.
can someone help me, thank you in advance!

ghosttester007_0-1604938944758.png

 

0 Likes
Accepted solutions (1)
1,966 Views
21 Replies
Replies (21)
Message 2 of 22

Kent1Cooper
Consultant
Consultant

[Maybe I misunderstand, but is there some reason you can't just pick on the Block, instead of in the middle of nowhere inside it?]

Kent Cooper, AIA
Message 3 of 22

Moshe-A
Mentor
Mentor

@Anonymous  hi,

 

Why would you do that? why not picking the attribute or the block edge?

 

Moshe

 

Message 4 of 22

Anonymous
Not applicable

@Kent1Cooper is for a sub-function,
I have several blocks inside this self and I would like to know which tag they belong to.

0 Likes
Message 5 of 22

Anonymous
Not applicable

@Moshe-A 

ghosttester007_1-1604940408533.png

 

0 Likes
Message 6 of 22

Moshe-A
Mentor
Mentor

post the later sample dwg

 

and what do you mean by 'get base point'? 

base point of that block? center point of that circle?

 

Message 7 of 22

Anonymous
Not applicable
0 Likes
Message 8 of 22

ВeekeeCZ
Consultant
Consultant

If you have another way to get the name, I would recommend that. The method would be complicated and unreliable.

Also - can you get that be selection an attribute? Or that's just a simplified example? Edit: I see the picture.

 

I would suggest posting some REAL dwg or at least a picture.

0 Likes
Message 9 of 22

cadffm
Consultant
Consultant

Quick start:

Start with a  ssget-FENCE,  with an insert filter set (if you can set a filter by blockname),

first point of fence is the "inside" point and the second one is near to to Mars or 'Extends variable.

If selection set is created, use (ssname myselset 0) to get the insert entity, in group code 2 you see the block name.

(For dynamic block variants: effectivname property)

 

And then starts the work.. overlapping objects. Which one is the right one?

UCS OCS WCS, current view plane. It's possible you find some rocks for stumbling

 

Sebastian

0 Likes
Message 10 of 22

Kent1Cooper
Consultant
Consultant

Are the larger outline Blocks with the XXX / YYY Attributes always arranged the same way?  With one at 0,0 at its lower left, and any other(s) always coinciding along an edge [maybe in multiple directions], but always the same size, and with their insertion points always in the same place on them [upper left corner in your example]?  If so, the location of one of the inside Blocks' insertion point could be used to find which "grid" portion it's in, and the corresponding outline Block should be determinable from that.

Kent Cooper, AIA
Message 11 of 22

Anonymous
Not applicable

I understand, so there is no native function for this ??
I was going in that direction, but there are problems that I don't know how to solve.
Thinking about using the function :getvalue to explode and restore the block but it doesn't seem possible.

using the function in the attached .dwg, it returns exactly what I need with polyline and text.

 

 

(defun :getvalue ( pntt  / *error* insidepoly RemoveAdjacentDuplicates ent maxpt minpt osm pt ss )
  ;
  
  (defun *error* (msg) (setvar "OSMODE" osm) (princ (strcat "Error: " msg)))
  
  (defun insidepoly (pt ent ray / ints)
    (setq ints (vlax-invoke (vlax-ename->vla-object ent) 'intersectwith ray acExtendNone))
    (if (eq (rem (length ints) 6) 3)
      ent
    )
  )
  
  (defun RemoveAdjacentDuplicates (lst / tst)
    (setq tst lst)
    (vl-remove nil (mapcar '(lambda (x) (if (null (equal x (car (setq tst (cdr tst))) 1e-8)) x)) lst))
  )
  
  (defun :selset-to-list (selset / lst iter)
  (setq iter 0)
  (repeat (sslength selset)
    (setq lst (cons (ssname selset iter) lst)
          iter (1+ iter))
  )
  (reverse lst)
)
  
  (setq osm (getvar "OSMODE"))
  (setvar "OSMODE" 0)
  (if 
    (and 
      (setq pt pntt)
      ;(setq pt (getpoint))
      (setq ss (ssget "_X" (list '(0 . "*POLYLINE") (cons 8 "laytest"))))
      (setq ray (vla-AddRay (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-3d-point pt) (vlax-3d-point (polar pt 0 1))))
      (setq ent (vl-some '(lambda (x) (insidepoly pt x ray)) (:selset-to-list ss)))
    )
    (progn
      (setq ntxt (ssget "_WP" (RemoveAdjacentDuplicates (mapcar 'cdr (vl-remove-if-not '(lambda (x) (eq (car x) 10)) (entget ent)))) (list '(0 . "TEXT,MTEXT")(cons 8 "laytest")))
            ntxt (if ntxt (cdr (assoc 1 (entget (ssname ntxt 0)))))
      )
    )
  )
  (vla-Delete ray)
  (setvar "OSMODE" osm)
  (setq bairro ntxt)
)

;;(:getvalue (getpoint))
(:getvalue (getpoint))
0 Likes
Message 12 of 22

ronjonp
Advisor
Advisor

Maybe something as simple as this? 

(setq e (bpoly (getpoint)))

It will return the ename of the boundary that you can use to get your selection set. 

0 Likes
Message 13 of 22

hak_vz
Advisor
Advisor
Accepted solution
(defun c:insider ( / LM:boundingbox  LM:getattributevalue sort_clockwise pt ss i j in e eo bb p1 p2 pt sd)
(defun LM:boundingbox ( obj / a b lst )
    (if
        (and
            (vlax-method-applicable-p obj 'getboundingbox)
            (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'a 'b))))
            (setq lst (mapcar 'vlax-safearray->list (list a b)))
        )
        (mapcar '(lambda ( a ) (mapcar '(lambda ( b ) ((eval b) lst)) a))
           '(
                (caar   cadar)
                (caadr  cadar)
                (caadr cadadr)
                (caar  cadadr)
            )
        )
    )
)


(defun LM:getattributevalue ( blk tag / val enx )
    (while
        (and
            (null val)
            (setq blk (entnext blk))
            (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk)))))
        )
        (if (= (strcase tag) (strcase (cdr (assoc 2 enx))))
            (setq val (cdr (assoc 1 (reverse enx))))
        )
    )
)

(defun sort_clockwise (ptlist)
(setq p (list (/ (apply '+ (mapcar 'car ptlist)) (length ptlist))(/ (apply '+ (mapcar 'cadr ptlist)) (length ptlist))))
(vl-sort ptlist '(lambda (a b) (> (sin (- (angle p a) (angle p b))) -1e-14)))
)
(defun vectorSide (v1 v2 p / r *fuzz*)
(setq r (- (* (-(car v2)(car v1))(-(cadr p)(cadr v1)))
           (* (-(cadr v2)(cadr v1))(-(car p)(car v1)))
        )
	*fuzz* 1e-10
)
(cond ((equal r 0.0 *fuzz*) 0) (t (fix (/ (abs r) r))))
)

(setq pt (getpoint "\nPick Point >"))
(setq ss (ssget "X" '((0 . "INSERT"))))
(setq i 0 in nil)

(while (< i (sslength ss))
(setq e (ssname ss i))
(setq eo (vlax-ename->vla-object e))
(setq bb (sort_clockwise (LM:BOUNDINGBOX eo)))
(setq bb (append bb (list(car bb))) sd nil)
(setq j -1 r -1)
(while (< (setq j (1+ j)) (-(length bb) 1))
(setq p1 (nth j bb) p2 (nth (+ j 1) bb) sd (cons (vectorSide p1 p2 pt) sd))
)
(if (=(apply '+ sd) -4) (setq in i))
(setq i (+ i 1))
)
(cond 
((and in)
(princ (strcat"\n Point inside  " (LM:getattributevalue (ssname ss in) "ATTx")))
)
)
)

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 14 of 22

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

Maybe something as simple as this? 

(setq e (bpoly (getpoint)))

It will return the ename of the boundary that you can use to get your selection set. 


Is there a (bpoly) AutoLisp function that's not documented?  It seems so in quick trial, but without documentation I can't tell how the result might be affected by surrounding conditions.  But whether I use the insertion point of an inner Block for the point in that, or in a BPOLY command, since the insertion point is in the middle of the little Block [in the sample drawing, at least], the resulting Polyline is just within that Block, and does not go to the outer one that would presumably outline the surrounding Block with the Attribute they want to get the value from.  If there's ever anything like a Line drawn across the surrounding one, that will limit the resulting Polyline's reach, so that using the Polyline's vertices  in the WP option in (ssget) won't find that outer Block.

Kent Cooper, AIA
0 Likes
Message 15 of 22

Anonymous
Not applicable

@hak_vz  Thanks, it works great.

thanks to the others for the time spent!

 

 

0 Likes
Message 16 of 22

Sea-Haven
Mentor
Mentor

Even though answered as the bpoly sits exact on top so some times returns nil offset out a small amount use that for the WP. 

 

(command "bpoly" (getpoint "\nPick internal point ") "")
(setq ent (entlast))
(vla-offset ent 10)
(if plent (setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (entlast))))))
(command "erase" (entlast) "")
(setq ss (ssget "WP"co-ord))
(setq ent (entget (ssname ss 0)))
0 Likes
Message 17 of 22

hak_vz
Advisor
Advisor

@Anonymous  My code may need some testing and final touches. Test it on your real drawings, and report how it works.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 18 of 22

ВeekeeCZ
Consultant
Consultant

@Anonymous wrote:

I understand, so there is no native function for this ??
I was going in that direction, but there are problems that I don't know how to solve.
Thinking about using the function :getvalue to explode and restore the block but it doesn't seem possible.

using the function in the attached .dwg, it returns exactly what I need with polyline and text.


 

Well, it's hard to assume which method would be more suitable for the job without seeing the actual scale of the issue.

Personally, I would try to avoid the pick-inside approach. Whether it's (command "bpoly"), or it's lisp (and older?) version (bpoly) or any user-made routine using the same ray casting method... Knowing how reliable is point-hatching using build-in commands... better not.

So preferably I would go the other way around - collecting all boundaries first, then if the drawing is simple enough, use simply the ssget function  with its window option. If possible use bounding boxes.. rather than Explode.. much more effective.... this is what suggests the others too... so.

0 Likes
Message 19 of 22

ronjonp
Advisor
Advisor

@Kent1Cooper wrote:

@ronjonp wrote:

Maybe something as simple as this? 

 

 

(setq e (bpoly (getpoint)))

 

 

It will return the ename of the boundary that you can use to get your selection set. 


Is there a (bpoly) AutoLisp function that's not documented?  It seems so in quick trial, but without documentation I can't tell how the result might be affected by surrounding conditions.  But whether I use the insertion point of an inner Block for the point in that, or in a BPOLY command, since the insertion point is in the middle of the little Block [in the sample drawing, at least], the resulting Polyline is just within that Block, and does not go to the outer one that would presumably outline the surrounding Block with the Attribute they want to get the value from.  If there's ever anything like a Line drawn across the surrounding one, that will limit the resulting Polyline's reach, so that using the Polyline's vertices  in the WP option in (ssget) won't find that outer Block.


@Kent1Cooper Thanks for the description Kent .. this is essentially describing what the boundary command does. My offering was just an idea not a fool proof solution. The thought was to use a crossing selection for the check but even that could be fooled with adjacent blocks. 🍻

 

This is probably how I'd approach this problem after thinking about it a bit more 🙂

 

 

(defun c:foo (/ a c d p r s)
  ;; Viewport Extents  -  Lee Mac
  ;; Returns two WCS points describing the lower-left and
  ;; upper-right corners of the active viewport.
  (defun lm:viewportextents (/ c h v)
    (setq c (trans (getvar 'viewctr) 1 0)
	  h (/ (getvar 'viewsize) 2.0)
	  v (list (* h (apply '/ (getvar 'screensize))) h)
    )
    (list (mapcar '- c v) (mapcar '+ c v))
  )
  ;; RJP » 2020-11-10
  (setq a (lm:viewportextents))
  (cond	((and (setq p (getpoint "\nPick a point:"))
	      (setq s (ssget "_C" (car a) (cadr a) '((0 . "INSERT") (66 . 1))))
	      (setq s (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))
	 )
	 (while	(and (null r) (car s))
	   (vla-getboundingbox (vlax-ename->vla-object (car s)) 'c 'd)
	   (mapcar 'set '(c d) (mapcar 'vlax-safearray->list (list c d)))
	   (cond ((and (<= (car c) (car p) (car d)) (<= (cadr c) (cadr p) (cadr d)))
		  (setq r (car s))
		  (redraw r 3)
		  (if (= 'str (type (vl-catch-all-apply 'getpropertyvalue (list r "ATTx"))))
		    (alert (getpropertyvalue r "ATTx"))
		    (alert "Block does not have 'ATTx'TAGNAME!")
		  )
		 )
	   )
	   (setq s (cdr s))
	 )
	)
  )
  (princ)
)

 

 

 

Message 20 of 22

Sea-Haven
Mentor
Mentor

(setq e (bpoly (getpoint))) not supported Bricscad V20 maybe V21 ?

0 Likes