Lisp to insert block on MLine

Lisp to insert block on MLine

smallƑish
Advocate Advocate
4,433 Views
38 Replies
Message 1 of 39

Lisp to insert block on MLine

smallƑish
Advocate
Advocate

Please have look to the GIF illustration for easy understanding.

smallish_0-1744906124930.gif

 

On the mline ( always single segmented) 2 mlines intersection on 45Dgr. while selecting the both mline. need a lisp automation to insert the "ELB_45"  Block referring mline orientation. Mline Style Name is "DR"

 

Cad file attached 

0 Likes
Accepted solutions (4)
4,434 Views
38 Replies
Replies (38)
Message 2 of 39

_Tharwat
Advisor
Advisor
Accepted solution

Here you go.

(defun c:Test (/ int ent sel bkn pts crs blk ml1 ml2 )
  ;;--------------------------------------------;;
  ;; Author : Tharwat Al Choufi			;;
  ;;						;;
  ;; www.AutolispPrograms.WordPress.com		;;
  ;;--------------------------------------------;;
  (and (setq bkn "ELB_45")
       (or (tblsearch "BLOCK" bkn)
           (alert (strcat "Block name < " bkn " > was not found in this dwg.!"))
           )
       (setq sel (ssget '((0 . "MLINE"))))
       (or (= (sslength sel) 2)
           (alert "Must select only two Mline objects.! Try again")
           )
       (or (progn
             (foreach itm (entget (ssname sel 0))
               (and (= (car itm) 11)
                    (setq ml1 (cons (cdr itm) ml1))
                    )
               )
             (foreach itm (entget (ssname sel 1))
               (and (= (car itm) 11)
                    (setq ml2 (cons (cdr itm) ml2))
                    )
               )
             )
           t
           )
       (vl-some '(lambda (u) (and (or (equal (car ml1) u 1e-4) (equal (cadr ml1) u 1e-4)) (setq crs u))) ml2)
       (mapcar '(lambda (u) (or (equal crs u 1e-4) (setq pts (cons u pts))))
               (append ml1 ml2)
               )
       (or (equal (rem (abs (- (angle (car pts) crs) (angle crs (cadr pts)))))
                  (* pi 0.25)
                  1e-4
                  )
           (alert "Obtained angle is not equal 45 Degree.!")
           )
       (setq blk (entmakex (list '(0 . "INSERT")
                                 (cons 10 crs)
                                 (cons 2 bkn)
                                 (cons 50 (- (angle (car pts) crs) (* pi 0.5)))
                                 '(41 . 1.0)
                                 '(42 . 1.0)
                                 '(43 . 1.0)
                                 )
                           )
             )
       (if (minusp (sin (- (angle (car pts) crs) (angle (car pts) (cadr pts)))))
         (progn
           (vlax-invoke (setq blk (vlax-ename->vla-object blk)) 'mirror (car pts) crs)
           (vla-delete blk)
           )
         )
       )
  (princ)
  ) (vl-load-com)

 

Message 3 of 39

smallƑish
Advocate
Advocate

That's such a classic code.  The error handling side is so brilliant. Loved it. And thank you so much.

 

Once again. Thank you so much ! 

0 Likes
Message 4 of 39

Moshe-A
Mentor
Mentor
Accepted solution

@smallƑish  hi,

 

check ELB45 command.

 

Note:

Previously your elbow90 and elbowT where suitable to mline width 20, in elbow45 width is 50 - how are you handling it?

 

enjoy

Moshe

 

 

 

 

Message 5 of 39

smallƑish
Advocate
Advocate

Thank you so much—just like before, you made this so much easier, and it works perfectly for multiple pairs.

Regarding pipe size ,At first, I had some difficulty when working with different pipe sizes. But later, I adjusted the block size to 1mm and created a global variable (which we can set as pipe size) to multiply with the block insertion scale factor . This way, it works for any pipe size no limitations. Your code is really well-structured, which made it easy for someone like me to modify and adapt. Now we cant live with out those codes anymore. its important as oxygen to work  ❤️❤️❤️❤️

0 Likes
Message 6 of 39

Moshe-A
Mentor
Mentor

thank you very much,

i was worried about the block scale and RETREAT value.

 

for the best result the blocks should be small as 1x1 unit and the lisp can read the mline width and determines the block scale and the retreat value.

 

Moshe

 

 

 

 

0 Likes
Message 7 of 39

DOODLEANU
Enthusiast
Enthusiast

That's nice

0 Likes
Message 8 of 39

smallƑish
Advocate
Advocate

I divided the RETREAT value by 20 (since it was designed for 20mm), then multiplied it by the pipe size global variable. That way, it aligns perfectly with the blocks, which are 1x1.

0 Likes
Message 9 of 39

Moshe-A
Mentor
Mentor

I understand there are some mlines width (20, 50 and maybe others) so why not reading the width from the selected mline? this enable you to use the command without the need to change the code manually. 

 

And i am thinking even going further by combining between elb90 and elb45 where the block name would be determines according to the angle between pairs of mlines.

 

??

 

Moshe

0 Likes
Message 10 of 39

smallƑish
Advocate
Advocate

Yah true, taking Scale factor from MLine width that's an amazing idea !!!!

 

I have made a dcl for easy usage 

kindly have a look to the same. 

Hence never change touch the code manually

0 Likes
Message 11 of 39

smallƑish
Advocate
Advocate

Next, I believe the process can be more automated.

The idea is to select lines or polylines, then run the makedrawings command, which will:

Execute the l2m command and store the multiline selection.

Automatically run the elbow, tee, 45, and arrow commands in sequence.

Ideally, this completes the layout in one click, with only balancing verification and corrections.

0 Likes
Message 12 of 39

smallƑish
Advocate
Advocate

Facing issues while loading the lisp. 

Hence VLX file attached for your review.

0 Likes
Message 13 of 39

Sea-Haven
Mentor
Mentor

Just a comment "Next, I believe the process can be more automated." why would you not just use a pline of multiple segments, the just imply pipe diameter so insert the correct angle block, then draw the outside lines. I seem to remember some code about drawing next point at 22.5, 45, 90 etc. Not something I have.

0 Likes
Message 14 of 39

Moshe-A
Mentor
Mentor

@smallƑish  hi,

 

Attached new elbow.lsp that combines elb45 + elb90 + l2m all to one elbow command.

if you select lines (or plines) you will be prompt to specify mline scale.

i modify the blocks, actually reduce them to 1 drawing unit (1x1) such as when them are insert they scale by mline width which

is automatically read from the selected mlines (start using these modified blocks)

 

about elbowT is a different story and in the coming days i would try to combine it also 

did not have the time to look what you post, maybe after this it is less relevant?

 

enjoy

Moshe

 

 

 

 

Message 15 of 39

smallƑish
Advocate
Advocate

smallish_0-1745390483563.gif

Ooooooohhhhh.. I have requested for a hut, you gave us Burj Khalifa. 

Thank you so much again and again !! 

0 Likes
Message 16 of 39

Moshe-A
Mentor
Mentor

@smallƑish ,

 

thank you for that

And i hope you did not forget that you can select lines and/or polylines and they are converted to mlines, plus you are free to pick any mline width.

 

Moshe

 

0 Likes
Message 17 of 39

smallƑish
Advocate
Advocate

smallish_0-1745393881949.gif

 

Sure got that too. that's the Supreme 

0 Likes
Message 18 of 39

Moshe-A
Mentor
Mentor

@smallƑish 

 

it's amazing it is working when on the same mline there is elbow on both sides i was not aware on that? does it was that always???

 

 

0 Likes
Message 19 of 39

smallƑish
Advocate
Advocate

Of course, it's amazing! At the end of the MLINE connects with some blocks, which always vary. As of now, it's perfect. If you are looking to improve it, arrow insertion could be an option to add part of the routine. 

 

(defun c:ARW (/ mline-list mline start-point end-point ARW-block mid-point i coords)
     

  (setq mline-list (ssget '((0 . "MLINE"))))
  (setq ARW-block "D_ARW") ; Block name

  (if mline-list
    (progn
      (setq i 0)
      (repeat (sslength mline-list)
        (setq mline (ssname mline-list i))
        (setq coords (vlax-safearray->list (vlax-variant-value (vla-get-coordinates (vlax-ename->vla-object mline)))))
        ;(setq start-point (vlax-curve-getStartPoint mline))
        ;(setq end-point (vlax-curve-getEndPoint mline))
        (setq start-point (list (nth 0 coords) (nth 1 coords))) ; 2D
        (setq end-point (list (nth 3 coords) (nth 4 coords)))
        (setq mid-point (list (/ (+ (car start-point) (car end-point)) 2.0)
                              (/ (+ (cadr start-point) (cadr end-point)) 2.0)))
        
        (command "_.INSERT" ARW-block mid-point EP_WS_PIPE_SIZE EP_WS_PIPE_SIZE  (angtos (angle start-point end-point))) ; Insert block with correct rotation
        (setq i (1+ i)) ; Increment index
      )
    )
  )
  (princ)
)

 

0 Likes
Message 20 of 39

Moshe-A
Mentor
Mentor

@smallƑish ,

 

that's very nice i see you know some lisp 🙏

so this is for marking the pipe work flow?

and the angle from start-point to end-point but what would happen if the mline is drawn the opposite way?

and how to control the flow system as a whole?

 

tough questions? 😀

 

Moshe

 

 

 

 

0 Likes