Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

NEW TO LISP - create a line with text offset

24 REPLIES 24
Reply
Message 1 of 25
Yunlena
2961 Views, 24 Replies

NEW TO LISP - create a line with text offset

Hey all,

 

I am a beginner at LISP and this is a bit out of my league... and I'm trying to create a lisp where I can draw a polyline between 2 points that also places text with the actual distance offset above the line.

 

I did find this post and thought it was helpful... but alas, I'm not quite catching on..

 

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/need-labels-for-storm-pipe-lisp/td-p/...

 

Any help appreciated.

 

Thanks!

Christina

Best,
Christina
-------
Map 3D 2019 | Civil 3D 2019
Windows 10 | Lenovo P50S
24 REPLIES 24
Message 2 of 25
Hallex
in reply to: Yunlena

Please post a drawing with pipe label example
drown with your current settings and explain
a little more, or just upload a picture
_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 3 of 25
pbejse
in reply to: Yunlena


@ckako301 wrote:

Hey all,

 

I am a beginner at LISP and this is a bit out of my league... and I'm trying to create a lisp where I can draw a polyline between 2 points that also places text with the actual distance offset above the line.

 

Any help appreciated.

 

Thanks!

Christina


 

Try this oh so simple code

 

(Defun c:TOPL (/ pt1 pt2)  ; Text over Polyline
;; pBe 07May2013 ;; (setq TxtHt (cond ((getreal (strcat "\nEnter Text Height" (if TxtHt (strcat " <" (rtos TxtHt) ">: ") ": " ) ) ) ) (TxtHt) ) ) (setvar "cmdecho" 0) (if (setq pt1 (getpoint "\nPick the first Point: ")) (progn (command "_Pline" pt1) (while (> (getvar "CMDACTIVE") 0) (if (setq pt2 (getpoint pt1 "\nPick Next point:")) (progn (entmakex (list (cons 0 "TEXT") (cons 10 (Setq p_ (polar (mapcar '(lambda (x y) (* 0.5 (+ x y)) ) pt1 pt2 ) (+ (setq ang (angle pt1 pt2)) (/ pi 2.0)) (* 0.75 TxtHt) ) ) ) (cons 11 p_) (cons 40 TxtHt) (Cons 50 ang) '(72 . 4) '(73 . 3) (cons 1 (rtos (distance pt1 pt2) 2 2) ) ) ) (setq pt1 pt2) (command pt2) ) (command "") ) ) ) ) (princ) )

 

Dont hesitate to ask if you have any questions.

 

HTH

Message 4 of 25
stevesfr
in reply to: pbejse

@pbejse
the program is not placing the distance at all for me. I must have a setting wrong somehow. any suggestions? is it working ok for others?
steve
Message 5 of 25
pbejse
in reply to: stevesfr


@stevesfr wrote:
@pbejse
the program is not placing the distance at all for me. I must have a setting wrong somehow. any suggestions? is it working ok for others?
steve

It could be anything from text style to ucs. Text Height too small/big  perhaps? 

Can you paste a sample drawing.

 

 UCS friendlly <attached>

 

 

Message 6 of 25
Yunlena
in reply to: pbejse

pbejse,

 

Thank you so much!  I am going to try this right away.

 

I'm trying to learn how to write lisp and create stuff - I think the biggest hurdle for me is not knowing syntax. For instance, what is "progn", "strcat" & "cons"??

 

Thank you again!

 

Christina

 

Best,
Christina
-------
Map 3D 2019 | Civil 3D 2019
Windows 10 | Lenovo P50S
Message 7 of 25
stevesfr
in reply to: pbejse

attached is sample dwg where program not working.

thanks for any help why its not working/placing text

Message 8 of 25
pbejse
in reply to: stevesfr


@stevesfr wrote:

attached is sample dwg where program not working.

thanks for any help why its not working/placing text


The previous code draw and put the text on top

 

now . forf existing lines

 

(Defun c:TOL (/ pt1 pt2 _trans)  ; Text over Polyline
;; pBe 07May2013 ;;
  (setq TxtHt (cond
                ((getreal (strcat "\nEnter Text Height"
                                  (if TxtHt
                                    (strcat " <" (rtos TxtHt) ">: ")
                                    ": "
                                  )
                          )
                 )
                )
                (TxtHt)
              )
  )
  (setq _trans (lambda (p)(trans p 1 0)))
  (if (setq pt1 (getpoint "\nPick the first Point: "))
      (while 
		(setq pt2 (getpoint pt1 "\nPick Next point:"))

            (entmakex
              (list
                (cons 0 "TEXT")
                (cons 10
                      (Setq p_  ( _trans  (polar
                                 (mapcar '(lambda (x y)
                                            (* 0.5 (+ x y))
                                          )
                                         pt1
                                         pt2
                                 )
                                 (+ (setq ang (angle  (_trans pt1)( _trans  pt2))) (/ pi 2.0))
                                 (* 0.25 TxtHt)
                               ) )
                      ) 
                )
                (cons 11 p_)
                (cons 40 TxtHt)
                (Cons 50 ang)
                '(72 . 1)
                '(73 . 1)
                (cons 1
                      (rtos (distance pt1 pt2) 2 2)
                )
              )
            )
            (setq pt1 pt2)
            
          )
          
)
  (princ)
)

 

Message 9 of 25
_Tharwat
in reply to: Yunlena

Hope you don't mind guys , and this is just for fun . Smiley Very Happy

 

(defun c:fun (/ *error* _LW _Grdraw p pt p1 ang e ents lw lst)
  ;;---		Tharwat 07. May. 2013		---;;
  (defun *error* (x)
    (redraw)
    (if ents
      (foreach x ents (entdel x))
    )
    (if lw
      (entdel lw)
    )
    (princ "\n*Cancel*")
  )
  (defun _LW (lst)
    (entmakex
      (append (list '(0 . "LWPOLYLINE")
                    '(100 . "AcDbEntity")
                    '(100 . "AcDbPolyline")
                    (cons 90 (length lst))
                    '(70 . 0)
              )
              (mapcar (function (lambda (x) (cons 10 x))) lst)
      )
    )
  )
  (defun _grdraw (st l / i)
    (setq i -1)
    (repeat (length l)
      (grdraw st (nth (setq i (1+ i)) l) 3 1)
      (setq st (nth i l))
    )
  )
  (if (setq p (getpoint "\n Specify first point :"))
    (progn
      (setq lst (cons p lst))
      (while
        (setq pt (getpoint "\n Next point :" p))
         (setq lst (cons pt lst)
               ang (angle p pt)
         )
         (_grdraw p lst)
         (if (and (<= ang (* pi 0.5))
                  (>= (* pi 1.5) ang)
             )
           (setq ang (+ ang pi))
         )
         (setq e (entmakex (list '(0 . "TEXT")
                                 (cons 40 (getvar 'textsize))
                                 '(71 . 0)
                                 '(72 . 1)
                                 '(73 . 2)
                                 (cons 1 (rtos (distance pt p) 2 4))
                                 (cons 10
                                       (setq p1
                                              (polar
                                                (mapcar (function (lambda (j k) (/ (+ j k) 2.)))
                                                        p
                                                        pt
                                                )
                                                (+ (* pi 0.5) ang)
                                                (* (getvar 'textsize) 1.35)
                                              )
                                       )
                                 )
                                 (cons 11 p1)
                                 (cons 50 ang)
                           )
                 )
         )
         (setq ents (cons e ents)
               p    pt
         )
      )
    )
  )
  (if lst
    (setq lw (_LW lst))
  )
  (redraw)
  (princ "\n Written by Tharwat Al Shoufi")
  (princ)
)

 

Message 10 of 25
stevesfr
in reply to: _Tharwat

Tharwat, almost perfect. But sometimes the text is updidedown when line drawn from lower left to upper right, and is placed correctly when line drawn from upper left to lower right. I should think the text should be right side up for any direction line is drawn.
A minor revision should make it perfect. Thanks
Steve
Message 11 of 25
stevesfr
in reply to: pbejse

This is great for existing lines. good work.
Message 12 of 25
_Tharwat
in reply to: stevesfr


@stevesfr wrote:
Tharwat, almost perfect. But sometimes the text is updidedown when line drawn from lower left to upper right, and is placed correctly when line drawn from upper left to lower right. I should think the text should be right side up for any direction line is drawn.
A minor revision should make it perfect. Thanks
Steve

Steve, I am surprized that you are the one whom following the thread and not the OP , but anyway try this code and let me know how things went with you .

 

and try to cancel the code while you are running it .

 

(defun c:fun (/ *error* keepAngleLogic _Grdraw p pt p1 ang e ents lw lst
             )
  ;;---		Tharwat 07. May. 2013		---;;
  (defun *error* (x)
    (redraw)
    (if ents
      (foreach x ents (entdel x))
    )
    (if lw
      (entdel lw)
    )
    (princ "\n*Cancel*")
  )
  (defun keepAngleLogic (ang)
    (cond ((and (>= ang (/ pi 2.)) (<= ang (+ pi (/ pi 2.))))
           (setq ang (+ ang pi))
          )
          ((= ang pi) (setq ang (- ang pi)))
          ((> ang 0.0) (setq ang (- ang (+ pi pi))))
    )
    ang
  )
  (defun _grdraw (st l / i)
    (setq i -1)
    (repeat (length l)
      (grdraw st (nth (setq i (1+ i)) l) 3 1)
      (setq st (nth i l))
    )
  )
  (if (setq p (getpoint "\n Specify first point :"))
    (progn
      (setq lst (cons p lst))
      (while
        (setq pt (getpoint "\n Next point :" p))
         (setq lst (cons pt lst)
               ang (keepAngleLogic (angle p pt))
         )
         (_grdraw p lst)
         (setq e (entmakex (list '(0 . "TEXT")
                                 (cons 40 (getvar 'textsize))
                                 '(71 . 0)
                                 '(72 . 1)
                                 '(73 . 2)
                                 (cons 1 (rtos (distance pt p) 2 4))
                                 (cons 10
                                       (setq p1
                                              (polar
                                                (mapcar (function (lambda (j k) (/ (+ j k) 2.)))
                                                        p
                                                        pt
                                                )
                                                (+ (* pi 0.5) ang)
                                                (* (getvar 'textsize) 1.35)
                                              )
                                       )
                                 )
                                 (cons 11 p1)
                                 (cons 50 ang)
                           )
                 )
         )
         (setq ents (cons e ents)
               p    pt
         )
      )
    )
  )
  (if lst
    (setq
      lw (entmakex
           (append (list '(0 . "LWPOLYLINE")
                         '(100 . "AcDbEntity")
                         '(100 . "AcDbPolyline")
                         (cons 90 (length lst))
                         '(70 . 0)
                   )
                   (mapcar (function (lambda (x) (cons 10 x))) lst)
           )
         )
    )
  )
  (redraw)
  (princ "\n Written by Tharwat Al Shoufi")
  (princ)
)

 

Message 13 of 25
stevesfr
in reply to: _Tharwat

@Tharwat. the program is perfect !! however if one hits Esc at any time, all the lines and text is erased !! that is OK, one just has to realize this and start over. Nice coding, thanks for your attention ! !
hope OP likes it. Steve
Message 14 of 25
_Tharwat
in reply to: stevesfr


@stevesfr wrote:
@Tharwat. the program is perfect !! however if one hits Esc at any time, all the lines and text is erased !! that is OK, one just has to realize this and start over. Nice coding, thanks for your attention ! !
hope OP likes it. Steve

You're welcome Steve . Smiley Happy

Message 15 of 25
pbejse
in reply to: stevesfr


@stevesfr wrote:

attached is sample dwg where program not working.

thanks for any help why its not working/placing text


I dont see anything  odd on your sample drawing. as far as i can tell the attached lisp codes should work. At any rate. the routine utilize the native Pline command to make as simple as possible for the benefit of the OP.

 


@ckako301 wrote:

pbejse,

 

I'm trying to learn how to write lisp and create stuff - I think the biggest hurdle for me is not knowing syntax. For instance, what is "progn", "strcat" & "cons"??

 

Christina

 


progn were used here in conjunction with IF function.
     "You can use progn to evaluate several expressions where only one expression is expected."
As such in the case with IF function

 

Strcat:
     "Returns a string that is the concatenation of multiple strings"

 

Example:
(setq str1 "Banana" str2 "cake" str3 "yumyum")
(Strcat str1 " " str2 " " str3)  "Banana cake yumyum" , where " " is a space 

 

Cons
     "Adds an element to the beginning of a list, or constructs a dotted list"
Example:
(setq list1 (list str2 str3)) -->("cake" "yumyum") 
(cons str1 list1) -->("Banana" "cake" "yumyum")

 

All those above can be found on the Autocad Help file [F1] or here 

 

Keep on coding Christina

 

Holler if you need more help

 

Message 16 of 25
Yunlena
in reply to: pbejse

 

Thanks pbejse.

 

I've kind of tried to tweak what you gave me (which was awesome as-is!) - I can get the text to be on the other side but I can't seem to "orient" the text to be "readable". I feel like that wouldn't be a dxf code, but an actual command? I also want to prompt the user for the distance info... I used the help and some forum stuff to try and figure out the dxf group codes - which are great, too - I just have to delve into it more.

 

Hope that makes sense..

 

Thanks!

Christina

 

(Defun c:DTOP (/ pt1 pt2 p_ ang)  ; Text over Polyline;; pbejse 07May2013, ADG ;;


  (setvar "cmdecho" 0) ;; to hide command line mumbo jumbo
  (if (setq pt1 (getpoint "\nPick the first Point: "))
    (progn   
      (command "_Pline" pt1)
       (while t
        (if (setq pt2 (getpoint pt1 "\nPick Next point:"))
          (progn
            (entmakex
              (list
                (cons 0 "TEXT")
                (cons 10
                      (Setq p_ (polar
                                 (mapcar '(lambda (x y)                                              (* 0.5 (+ x y))
                                          )
                                         pt1
                                         pt2					
                                 )
                                 (+ (setq ang (angle pt1 pt2)) (/ pi 2.0) (* 180)) 15
				 			
                                 
                               )		   
                      )
                )
                (cons 11 p_)
                (cons 40 9)
                (Cons 50 ang)
		
		(cons 7 "ROMAND")
                '(72 . 4)
                '(73 . 3)
                (cons 1
                      (strcat (rtos (distance pt1 pt2) 2 0) "'")
) ) ) (setq pt1 pt2) (command pt2) ) (command "") ) ) ) ) (princ) )
Best,
Christina
-------
Map 3D 2019 | Civil 3D 2019
Windows 10 | Lenovo P50S
Message 17 of 25
pbejse
in reply to: Yunlena


@ckako301 wrote:

 

Thanks pbejse.

 

I've kind of tried to tweak what you gave me (which was awesome as-is!) - I can get the text to be on the other side but I can't seem to "orient" the text to be "readable". I feel like that wouldn't be a dxf code, but an actual command? I also want to prompt the user for the distance info... I used the help and some forum stuff to try and figure out the dxf group codes - which are great, too - I just have to delve into it more.

 

Hope that makes sense..

 

Thanks!

Christina


The placement of the TEXT will depend on the direction of the pick point. You may have to add a sub to handle that if you always want the TEXT entity to be a particular side .Post an example to give us a better idea. 

 

That is easy enough Christina . I noticed you use the value 9 for height and 15 for distance from Text insertion point. 

 

On another note. When you used T argument for the  while loop , the only way to terminate the program is to press "cancel" , is that how you want it to end everytime?

 

Message 18 of 25
Yunlena
in reply to: pbejse

example.jpg

 

Hi!

 

My coworker recommended that I use T for the while loop - I just went with it. Hitting ESC to cancel works out fine 🙂

 

I've attached an example jpg file that shows that I can get the text to be on the other side but I need it to read (be oriented) the other way. And to also be able to type in the distance.

 

Thanks!

Christina

 

 

Best,
Christina
-------
Map 3D 2019 | Civil 3D 2019
Windows 10 | Lenovo P50S
Message 19 of 25
pbejse
in reply to: Yunlena


@ckako301 wrote:
Hi!

 

My coworker recommended that I use T for the while loop - I just went with it. Hitting ESC to cancel works out fine 🙂

 

I've attached an example jpg file that shows that I can get the text to be on the other side but I need it to read (be oriented) the other way. And to also be able to type in the distance.

 

Thanks!

Christina 

 


 

Can't say i agree with the recommendation though, No offense Christina what does your co-worker said about the text orientation anyway?  Smiley Happy

 

Anyways

 

(Defun c:TOPL (/ _Distfrom ang p_ pt1 pt2 _trans)  ; Text over Polyline
;; pBe 07May2013 ;;
(defun _Distfrom (val df)
	(initget 6)
	  (setq val (cond
	                ((getreal (strcat "\nEnter Text Distance from object"
	                                  (if (And val (>= val df))
	                                    (strcat " <" (rtos val) ">: ")
	                                    ": "
	                                  )
	                          )
	                 )
	                )
	                (val)
	              )
	  )
  (if (< val df)(progn (princ "\nMust be equal or greater that Text Height <9.0>") (_Distfrom val df))
    	 val))
  (setvar "cmdecho" 0)
  (setq _trans (lambda (p)(trans p 1 0)))
  (setq d (_DISTFROM d 9));<-- "9" your preferred text height
  (if (setq pt1 (getpoint "\nPick the first Point: "))
    (progn
      (command "_Pline" pt1)
      (while (> (getvar "CMDACTIVE") 0)
        (if (setq pt2 (getpoint pt1 "\nPick Next point:"))
          (progn
            (entmakex
              (list
                (cons 0 "TEXT")
                (cons 10
                      (Setq p_  ( _trans  (polar
                                 (mapcar '(lambda (x y)
                                            (* 0.5 (+ x y))
                                          )
                                         pt1
                                         pt2
                                 )
                                 (+ (setq ang (angle  (_trans pt1)( _trans  pt2))) (* pi 1.5))
                                 d
                               ) )
                      ) 
                )
                (cons 11 p_)
                '(40 . 9);<-- your prefered text height
                (Cons 50 
			(if (and
			(> ang (/ pi 2))
			(<= ang (* pi 1.5))
			)  (+ ang pi) ang ))
                '(7 . "ROMAND")
                '(72 . 4)
                '(73 . 3)
                (cons 1
                      (rtos (distance pt1 pt2) 2 2)
                )
              )
            )
            (setq pt1 pt2)
            (command pt2)
          )
          (command "")
        )
      )
    )
  )
  (princ)
)

 

Make sure Romand Tesxt style is existing Christina.

 

HTH

Message 20 of 25
Yunlena
in reply to: pbejse

That code works wonderfully also.

 

However, I am actually looking to override the distance with text that can be input by the user (not the distance from the line for the text itself). I hope that makes sense.

 

Everything else works great - I even didn't change it back to T 🙂

 

I really appreciate your help on this!!

 

Thanks!

Christina

Best,
Christina
-------
Map 3D 2019 | Civil 3D 2019
Windows 10 | Lenovo P50S

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost