Mirror a Block around its base point

Mirror a Block around its base point

a.tawkXHKN6
Contributor Contributor
3,522 Views
13 Replies
Message 1 of 14

Mirror a Block around its base point

a.tawkXHKN6
Contributor
Contributor

I want a Lisp that Mirror a block around its base point:

1. Select the Block.

2. Mirror it around its base point, and delete the original.

0 Likes
Accepted solutions (2)
3,523 Views
13 Replies
Replies (13)
Message 2 of 14

ВeekeeCZ
Consultant
Consultant

Around the vertical axis, right?

 

(defun c:BMirror (/ s)
  (if (setq s (ssget "_:S:E"))
    (command "_.MIRROR" s "" "_non" (trans (cdr (assoc 10 (entget (ssname s 0)))) 0 1) "_non" "@0,1" "_Yes"))
  (princ)
  )

 

0 Likes
Message 3 of 14

a.tawkXHKN6
Contributor
Contributor

thanks for your reply. Can we consider the case when we have a rotated block so that the mirror line should be rotated as well? see attached image. 

0 Likes
Message 4 of 14

ВeekeeCZ
Consultant
Consultant
Accepted solution

Sure.

 

(defun c:BMirror (/ s d)  
  (if (and (setq s (ssget "_:S:E"))
	   (setq d (entget (ssname s 0))))
    (command "_.MIRROR"
	     s ""
	     "_non" (trans (setq p (cdr (assoc 10 d))) 0 1)
	     "_non" (trans (polar p (+ (/ pi 2) (cdr (assoc 50 d))) 1) 0 1)
	     "_Yes"))
  (princ)
  )
Message 5 of 14

Kent1Cooper
Consultant
Consultant

@a.tawkXHKN6 wrote:

thanks for your reply. Can we consider the case when we have a rotated block so that the mirror line should be rotated as well? see attached image. 


You don't need a Mirror command  for this, nor to extract the insertion point, nor calculate the direction of the appropriate axis, nor translate between coordinate systems, nor account for the possibility of running Object Snap modes, etc.  In the case of a Block defined in the way your image shows, you can just change the X scale factor to the negative of its current value.  In simplest terms:

 

(defun C:BMIP (/ blk bdata) ; = Block "Mirror" about Insertion Point
  (setq
    blk (car (entsel "\nSelect Block to Mirror: "))
    bdata (entget blk)
  )
  (entmod
    (subst
      (cons 41 (- (cdr (assoc 41 bdata))))
      (assoc 41 bdata)
      bdata
    )
  )
  (princ)
)

 

If you want to flip one about the horizontal  axis in relation to your base Block definition, just change the 41's to 42's to use the Y scale factor instead of X.

Kent Cooper, AIA
0 Likes
Message 6 of 14

a.tawkXHKN6
Contributor
Contributor

Can we tweak the lisp such that we can select more than one block at once? 

0 Likes
Message 7 of 14

Kent1Cooper
Consultant
Consultant
Accepted solution

@a.tawkXHKN6 wrote:

Can we tweak the lisp such that we can select more than one block at once? 


Again, in simplest terms and minimally tested:

(defun C:BMIP (/ ss n blk bdata) ; = Block "Mirror" about Insertion Point
  (if (setq ss (ssget "_:L" '((0 . "INSERT"))))
    (repeat (setq n (sslength ss)); then
      (setq
        blk (ssname ss (setq n (1- n)))
        bdata (entget blk)
      ); setq
      (entmod
        (subst
          (cons 41 (- (cdr (assoc 41 bdata))))
          (assoc 41 bdata)
          bdata
        ); subst
      ); entmod
    ); repeat
  ); if
  (princ)
); defun
Kent Cooper, AIA
0 Likes
Message 8 of 14

duongauduong07
Explorer
Explorer

You are Awesome, i find it for long time 

0 Likes
Message 9 of 14

meynvangurp
Explorer
Explorer

Hi this works fine when you don't have a text (attribute) in a block.

Can someone help me to fix this?

 

The problem I have is when using this LSP on a block with some text written in it, the text will stay in same position, will not mirror 

0 Likes
Message 10 of 14

komondormrex
Mentor
Mentor

setting 'mirrtext variable to 1 will allow to mirror texts and attributes

0 Likes
Message 11 of 14

meynvangurp
Explorer
Explorer
Where to place this in LSP?
0 Likes
Message 12 of 14

Kent1Cooper
Consultant
Consultant

MIRRTEXT won't do it by itself.  The problem is that an Attribute has its own entity name and entity data, and changing the entity data of the Block reference to reverse the X scale factor does not affect the Attribute's position.  I think it will be necessary to use an actual MIRROR command, under which the object selection of the Block reference will include selection of the Attribute.  The Attribute's position will then flip along with the rest of the Block, and the MIRRTEXT setting will then affect the reading direction of the Attribute.  One way of doing it:

(defun C:BMIP (/ ss n blk bdata) ; = Block "Mirror" about Insertion Point
  (if (setq ss (ssget "_:L" '((0 . "INSERT"))))
    (repeat (setq n (sslength ss)); then
      (setq
        blk (ssname ss (setq n (1- n)))
        bdata (entget blk)
      ); setq
      (command "_.mirror" blk "" "_non" (cdr (assoc 10 bdata)) "_non" "@0,1" "_yes")
    ); repeat
  ); if
  (princ)
); defun

 

Kent Cooper, AIA
Message 13 of 14

meynvangurp
Explorer
Explorer

Thanks, looks like this works.
One more question: This LISP will flip it vertically, what to change if I want to mirror it horizontally?

0 Likes
Message 14 of 14

Kent1Cooper
Consultant
Consultant

@meynvangurp wrote:
...: This script will flip it vertically, what to change if I want to mirror it horizontally?

[It's not a Script.  That word has a specific meaning in AutoCAD, and this isn't it.]

 

Change "@0,1" to "@1,0".

Kent Cooper, AIA