macro or lisp to offset a line to an exploded rectangle in the same layer as the source.

macro or lisp to offset a line to an exploded rectangle in the same layer as the source.

mkroll9in5in
Enthusiast Enthusiast
567 Views
4 Replies
Message 1 of 5

macro or lisp to offset a line to an exploded rectangle in the same layer as the source.

mkroll9in5in
Enthusiast
Enthusiast

I'm looking for a macro or LISP, now on LT 2024, to offset a line 1" to a 2.5" exploded rectangle in the same layer as the source. I have a macro that does a dbl. offset, but then I have to manually add lines connecting the ends. There can be a lot of them so I would like it to function very similar to an offset.

 

offset strip.jpg

0 Likes
Accepted solutions (1)
568 Views
4 Replies
Replies (4)
Message 2 of 5

Moshe-A
Mentor
Mentor
Accepted solution

@mkroll9in5in  hi,

 

here is a very nice one called XBAR 🤣

 

xbar starts with asking you...

(line 50) "Bar offset distance" which is the distance away from face/edge

(line 51) "Bar width" the width of the bar.

 

these value are saved as default for the duration of the current session.

 

(line 52) Select object(s): select lines (yes you can select multiple rectangles) to attach the bars.

 

Note:

the size the bar will be drawn is the outside of the rectangle. if the xbar cannot identifies the rectangle it will skip that face/edge.

 

i keep it Classic AutoLISP for it will be compatible with R2024 LT but i do not have LT so hope it will work.

 

enjoy,

Moshe

 

 

 

; Attach Bar to Lines
(defun c:xbar (/ askdist opposite_bar_side  ; local function
	         oset wth ss l ename elist p10 p11 p12 ang lay p0 p1 p2 p3)

 (defun askdist (msg def / ask)
  (initget (+ 2 4))
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def 2) ">: "))))
   (setq ask def)
   (setq def ask)
  ); if
 ); askdist

  
 ; return a point, the opposite size of bar
 (defun opposite_bar_side (ent cen start_ang rad / _genRays _genPoints ; local function
				                               points^ ss1 e t10 t11)

  ; anonymous functions 
  (setq _genRays   (lambda (dir n / lst) (reverse (repeat 6 (setq lst (cons (+ (* (/ pi 3) (setq n (1+ n))) dir) lst))))))
  (setq _genPoints (lambda () (mapcar (function (lambda (ang) (polar cen ang rad))) (_genRays start_ang -1))))  
   
  (if (and
	(setq ss1 (ssget "_cp" (_genPoints) '((0 . "line"))))
	(= (sslength ss1) 2)
      )
   (progn
    (ssdel ent ss1) ; remove current handled object
    (setq e (entget (ssname ss1 0)))
    (setq t10 (cdr (assoc '10 e)) t11 (cdr (assoc '11 e)))

    (if (> (distance cen t10) (distance cen t11)) t10 t11)
   ); progn
  ); if
 ); opposite_bar_side

   
 ; here start c:xbar
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")

 (if (= (getvar "userr1") 0.0)
  (setvar "userr1" 1.0)
 )

 (if (= (getvar "userr2") 0.0)
  (setvar "userr1" 2.5)
 )

 (if (and
       (setvar "userr1" (setq oset (askdist "Bar offset distance" (getvar "userr1"))))
       (setvar "userr2" (setq wth (askdist  "Bar width" (getvar "userr2"))))
       (setq ss0 (ssget '((0 . "line")))) 
     )
  (repeat (setq l (sslength ss0))
   (setq elist (entget (setq ename (ssname ss0 (setq l (1- l))))))
   (setq p10 (cdr (assoc '10 elist)))
   (setq p11 (cdr (assoc '11 elist)))
   (setq ang (angle p10 p11))

   (if (setq p12 (opposite_bar_side ename p10 (angle p10 p11) (+ oset wth)))
    (progn
     (setq ang (+ (angle p10 p12) pi))
     (setq lay (cdr (assoc '8 elist)))
     (setq p0 (polar p10 ang oset))
     (setq p1 (polar p11 ang oset))
     (setq p2 (polar p1  ang wth ))
     (setq p3 (polar p0  ang wth ))
    
     (command "._pline" "_none" p0 "_none" p1 "none" p2 "none" p3 "_close")
     (command "._chprop" "_si" (entlast) "_layer" lay "")
    ); progn
   ); if
    
  ); repeat
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)
  
 (princ)
); c:xbar

 

 

 

 

 

0 Likes
Message 3 of 5

mkroll9in5in
Enthusiast
Enthusiast

Thank you, That works great. I create buttons for my ribbon that will auto enter the values. Each icon displaying that value. also added * to the front of the macro so that is loops the command. *^C^C_xbar;_1;_2.13;\;

0 Likes
Message 4 of 5

Moshe-A
Mentor
Mentor

Fantastic 😀😀😀

 

 

0 Likes
Message 5 of 5

Moshe-A
Mentor
Mentor

@mkroll9in5in hi,

 

Here is an update  made fine tuning. now it will also work even the rectangle is incomplete meaning missing\broken edges or even on a lonely line 🤣

 

enjoy

Moshe

 

; Attach Bar to Lines
(defun c:xbar (/ askdist opposite_bar_side working_direction ; local functions
	         oset wth ss0 i ename elist p10 p11 ang0 p0 p1 p2 p3) 

 (defun askdist (msg def / ask)
  (initget (+ 2 4))
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def 2) ">: "))))
   (setq ask def)
   (setq def ask)
  ); if
 ); askdist

  
 ; return a point, the opposite size of bar
 (defun opposite_bar_side (ent cen start_ang rad / _genRays _genPoints ; local functions
				                   points^ ss1 e t10 t11)
  ; anonymous functions 
  (setq _genRays   (lambda (dir n / lst) (reverse (repeat 6 (setq lst (cons (+ (* (/ pi 3) (setq n (1+ n))) dir) lst))))))
  (setq _genPoints (lambda () (mapcar (function (lambda (ang) (polar cen ang rad))) (_genRays start_ang -1))))  
   
  (if (and
	(setq ss1 (ssget "_cp" (_genPoints) '((0 . "line"))))
	(= (sslength ss1) 2)
      )
   (progn
    (ssdel ent ss1) ; remove current handled object
    (setq e (entget (ssname ss1 0)))
    (setq t10 (cdr (assoc '10 e)) t11 (cdr (assoc '11 e)))

    (if (> (distance cen t10) (distance cen t11)) t10 t11)
   ); progn
  ); if
 ); opposite_bar_side

  
 (defun working_direction (/ figure_angle ; local function
			     p12 ang0)

  (defun figure_angle (a0 a1 / qang ; local function
		               a2)
   (defun qang (g0 g1 / g2)
    (if (> g0 g1)
     (setq g2 (- g0 g1))
     (setq g2 (- g1 g0))
    )

    (if (> g2 (* pi 1.5))
     (- g2 (* pi 1.5))
     g2)
   ); qang
   
   (if (<= (atof (angtos (qang (setq a2 (+ a0 (/ pi 2))) a1) 0 4)) (atof (angtos (/ pi 2) 0 4)))
    a2
    (- a0 (/ pi 2))
   ); if
  ); figure_angle

   
  ; here start working_direction
  (cond
   ((setq p12 (opposite_bar_side ename p10 (setq ang0 (angle p10 p11)) (+ oset wth)))
    (figure_angle ang0 (angle p12 p10))
   ); case
   ((setq p12 (opposite_bar_side ename p11 (setq ang0 (angle p11 p10)) (+ oset wth)))
    (figure_angle ang0 (angle p12 p11))
   ); case
   ( t ; lonely line, use right hand rule
    (+ ang0 (/ pi 2))
   ); case
  ); cond
 ); working_direction

  
 ; here start c:xbar
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")

 (if (= (getvar "userr1") 0.0)
  (setvar "userr1" 1.0)
 )

 (if (= (getvar "userr2") 0.0)
  (setvar "userr1" 2.5)
 )

 (if (and
       (setvar "userr1" (setq oset (askdist "Bar offset distance" (getvar "userr1"))))
       (setvar "userr2" (setq wth  (askdist "Bar width" (getvar "userr2"))))
       (setq ss0 (ssget '((0 . "line")))) 
     )
  (repeat (setq i (sslength ss0))
   (setq elist (entget (setq ename (ssname ss0 (setq i (1- i))))))
   (setq p10 (cdr (assoc '10 elist)))
   (setq p11 (cdr (assoc '11 elist)))
   (setq ang1 (working_direction))
   
   (setq p0 (polar p10 ang1 oset))
   (setq p1 (polar p11 ang1 oset))
   (setq p2 (polar p1  ang1 wth ))
   (setq p3 (polar p0  ang1 wth ))
    
   (command "._pline" "_none" p0 "_none" p1 "none" p2 "none" p3 "_close")
   (command "._chprop" "_si" (entlast) "_layer" (cdr (assoc '8 elist)) "")
  ); repeat
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)
  
 (princ)
); c:xbar

 

0 Likes