Jump to content

need help on text placement


LISP2LEARN

Recommended Posts

I'm trying to put the layer name on the middle of the line (not on mid point). And also how can I get also the angle of the line selected so i can place the text parallel to the line selected. Thanks.

 

 

(defun mip-text-entmake (txt pnt height rotation justification / ent_list)
 ;;; borrowed from ShaggyDoc
 ;;; http://www.caduser.ru/forum/index.php?PAGE_NAME=read&FID=23&TID=30276

 (setq  ent_list (list  '(0 . "TEXT")
    '(100 . "AcDbEntity")
    '(100 . "AcDbText")
    (list 10 (car pnt) (cadr pnt) 0.0)
    (cons 1 txt)
    (cons 40 height)
    (cons 7 (getvar "TEXTSTYLE"))
    (if justification
      (cond
        ((= justification "C")
         '(72 . 1)
        )
        ((= justification "R")
         '(72 . 2)
        )
        ((= justification "A")
         '(72 . 3)
        )
        ((= justification "M")
         '(72 . 4)
        )
        ((= justification "F")
         '(72 . 5)
        )
        (t
         '(72 . 0)
        )
      ) ;_ end of cond
      '(72 . 0)
    ) ;_ end of if
    (cons 50 rotation)
    (list 11 (car pnt) (cadr pnt) 0.0)
    ) ;_ end of list
  ) ;_ end of setq
  (setq ent_list (entmakex ent_list))
)



(defun C:TEST (/ selobj #line)
 
(setq selobj (entsel))

 (setq #line (cdr (assoc 8 (entget (car selobj)))))
 (and
   (setq pt (getpoint "\nPick center text point: "))
   (setq pt (trans pt 1 0))
   (mip-text-entmake
     #line           ;;; text
      pt                   ;;; point
     (getvar "TEXTSIZE") ;;; heigth
     [color="red"]0[/color]                     ;;; rotation
     "C"                   ;;; justification
     )
   )
 )

LINETAG.jpg

Link to comment
Share on other sites

Assoc 10 is start point and 11 is end point (angle start end) this is only for lines then (/ (distance start end ) 2.0) this is mid point distance, use (polar start angle distance) is mid point on line. A suggestion you can add a bit extra code and compare which end you have picked then swap start and end so text is correct side up. Face down and from right. like your image or add a rotate option "is text ok" N Rotate 180. use enter as "Y" else everything else is a No.

 

A important things the angles are always in radians does not use "units" etc.

Link to comment
Share on other sites

Keeping the code similar to what you have, the program could be something like:

 

(defun c:test1 ( / entity point elist )
 (if
   (and
     (setq entity (car (entsel)))
     (eq "LINE"   (cdr (assoc 0 (setq elist (entget entity)))))
     (setq point  (getpoint "\nSpecify Point on Line: "))
     (setq point  (trans point 1 0))
   )
   (entmakex
     (list
       (cons 0 "TEXT")
       (cons 7  (getvar 'TEXTSTYLE))
       (cons 40 (getvar 'TEXTSIZE))
       (cons 10 point)
       (cons 11 point)
       (cons 1  (cdr (assoc 8 elist)))
       (cons 50 (angle (cdr (assoc 10 elist)) (cdr (assoc 11 elist))))
       (cons 72 1)
       (cons 73 2)
     )
   )
 )
 (princ)
)

However the above will only work in UCS planes parallel to the WCS plane and also doesn't ensure that the specified point lies on the selected line.

 

If you didn't want to specify a point for the text, it could something like:

 

(defun c:test2 ( / ang entity norm point ) (vl-load-com)
 (if
   (and (setq entity (entsel))
     (not
       (vl-catch-all-error-p
         (setq point
           (vl-catch-all-apply 'vlax-curve-getclosestpointto
             (list (car entity) (trans (cadr entity) 1 0))
           )
         )
       )
     )
   )
   (progn
     (setq entity (car entity)
           norm   (trans '(0. 0. 1.) 1 0 t)
     )
     (setq ang
       (angle '(0. 0. 0.)
         (trans
           (vlax-curve-getfirstderiv entity
             (vlax-curve-getparamatpoint entity point)
           )
           0 norm
         )
       )
     )
     (if (and (< (/ pi 2.) ang) (<= ang (/ (* 3. pi) 2.)))
       (setq ang (- ang pi))
     )
     (setq point (trans point 0 norm))
     (entmakex
       (list
         (cons 0 "TEXT")
         (cons 7  (getvar 'TEXTSTYLE))
         (cons 40 (getvar 'TEXTSIZE))
         (cons 10 point)
         (cons 11 point)
         (cons 1 (cdr (assoc 8 (entget entity))))
         (cons 50 ang)
         (cons 72 1)
         (cons 73 2)
         (cons 210 norm)
       )
     )
   )
 )
 (princ)
)

The above code will also work in all UCS/Views and also with Arcs, Circles, Ellipses, Splines, Polylines.. etc

Link to comment
Share on other sites

Damn Lee.. You rock.. You consider everything that I wanted it to be. I added the while function and select only lines on my selection and it's all perfect now.

 

I've been dissecting every lisp that you write everyday and I'm learning a lot. I hope one day I can code like you. Thank you very much.

Link to comment
Share on other sites

Lee I've noticed that you tend to use entmakex in favour of vla-add and similar. Can I ask your reasoning? It is not a method that I tend to use often and I'm wondering if I'm missing something exciting lol.

Link to comment
Share on other sites

Thanks BIGAL, Lee's code did the job. I was doing that also at first, before I even post my thread but I couldn't figure out what's wrong. Can you point out on what I missed?

 

(defun C:test (/ p1 p2 angline)
(setq selobj (entget (entsel)))
(setq p1 (car (cdr (assoc 10 selobj))))
(setq p2 (car (cdr (assoc 11 selobj))))
(princ (angle p1 p2))
(princ)
)

 

 

 

 

(angle '(0. 0. 0.)
         (trans
           (vlax-curve-getfirstderiv entity
             (vlax-curve-getparamatpoint entity point)
           )
           0 norm
         )

 

Assoc 10 is start point and 11 is end point (angle start end) this is only for lines then (/ (distance start end ) 2.0) this is mid point distance, use (polar start angle distance) is mid point on line. A suggestion you can add a bit extra code and compare which end you have picked then swap start and end so text is correct side up. Face down and from right. like your image or add a rotate option "is text ok" N Rotate 180. use enter as "Y" else everything else is a No.

 

A important things the angles are always in radians does not use "units" etc.

Link to comment
Share on other sites

Thanks BIGAL, Lee's code did the job. I was doing that also at first, before I even post my thread but I couldn't figure out what's wrong. Can you point out on what I missed?

 

(defun C:test (/ p1 p2 angline)
(setq selobj (entget (entsel)))
(setq p1 (car (cdr (assoc 10 selobj))))
(setq p2 (car (cdr (assoc 11 selobj))))
(princ (angle p1 p2))
(princ)
)

 

 

This ... ?

 

(setq selobj (entget (car (entsel ))))
(setq p1 (cdr (assoc 10 selobj)))
(setq p2 (cdr (assoc 11 selobj)))
(princ (angle p1 p2))

Link to comment
Share on other sites

Damn Lee.. You rock.. You consider everything that I wanted it to be. I added the while function and select only lines on my selection and it's all perfect now.

 

I've been dissecting every lisp that you write everyday and I'm learning a lot. I hope one day I can code like you. Thank you very much.

 

Thanks LISP2LEARN, you're very welcome :)

 

And, as always, if you have any questions about any code I post, just ask and I'll be happy to explain things :)

 

Lee I've noticed that you tend to use entmakex in favour of vla-add and similar. Can I ask your reasoning? It is not a method that I tend to use often and I'm wondering if I'm missing something exciting lol.

 

A number of reasons.

 

LISP is designed for list manipulation and offers many functions to do so. This means many tasks are far more concise using the DXF data list and furthermore, you needn't use Variants and Safearrays.

 

The DXF structure allows you to modify any or all properties of the entity with a single call to an ent* function, without digging through each and every property separately. Also I find it much easier to make programs compatible in all UCS planes using Vanilla AutoLISP.

 

The Vanilla AutoLISP functions (such as entmake) are usually a whole lot faster than the Visual LISP equivalents.

 

Other than that, being profficient in Vanilla methods enables you to write programs for systems without access to Visual LISP.

 

Lee

Link to comment
Share on other sites

Thanks LISP2LEARN, you're very welcome :)

 

And, as always, if you have any questions about any code I post, just ask and I'll be happy to explain things :)

 

 

 

A number of reasons.

 

LISP is designed for list manipulation and offers many functions to do so. This means many tasks are far more concise using the DXF data list and furthermore, you needn't use Variants and Safearrays.

 

The DXF structure allows you to modify any or all properties of the entity with a single call to an ent* function, without digging through each and every property separately. Also I find it much easier to make programs compatible in all UCS planes using Vanilla AutoLISP.

 

The Vanilla AutoLISP functions (such as entmake) are usually a whole lot faster than the Visual LISP equivalents.

 

Other than that, being profficient in Vanilla methods enables you to write programs for systems without access to Visual LISP.

 

Lee

I appreciate the flexibility that is offered from lisp with regards to but I can't help think that hard coding (entmake[x]) with a constant list length is a somewhat wasteful implementation of it.

 

That said I agreee that the not having to use safeArrays, variants is definitely convenient

 

According to Autodesk vlisp functions are considerably more timely than their vanilla counterparts.

 

I definitely agree that proficiency in both (more so vanilla, given other programs such as powercad implement it) is important; I suppose it is just my preference to leave the vanilla methods for special occasions lol.

 

Cheers for the feedback.

Link to comment
Share on other sites

I appreciate the flexibility that is offered from lisp with regards to but I can't help think that hard coding (entmake[x]) with a constant list length is a somewhat wasteful implementation of it.

 

I don't understand the 'wasteful' remark of your point - could you elaborate?

Link to comment
Share on other sites

I don't understand the 'wasteful' remark of your point - could you elaborate?

 

Wasteful wasn't the best choice of word. Mainly legibility; not everyone knows what dxf groups 40 and 50 are at first glance yet anyone can read vla-put-textHeight and vla-put-rotation respectively, or any other property for that matter.

 

Also I should take this time to concede that whilst vlisp is intrinsically faster than vanilla, this is not the case for entmake.

Link to comment
Share on other sites

  • 3 weeks later...

I added the trim command and it works perfectly on all Autocad 2009 computers but we upgraded to 2011 and for some reason, it just put the layer name but doesn't trim the line. Any idea please... Thanks.

 

 

 

;;coded by Lee
(defun c:LTAG ( / ang entity norm point ) (vl-load-com)
(while
  (if
	(and (setq entity (entsel))
	  (not
		(vl-catch-all-error-p
		  (setq point
			(vl-catch-all-apply 'vlax-curve-getclosestpointto
			  (list (car entity) (trans (cadr entity) 1 0))
			)
		  )
		)
	  )
	)
	(progn
	  (setq entity (car entity)
			norm   (trans '(0. 0. 1.) 1 0 t)
	  )
	  (setq ang
		(angle '(0. 0. 0.)
		  (trans
			(vlax-curve-getfirstderiv entity
			  (vlax-curve-getparamatpoint entity point)
			)
			0 norm
		  )
		)
	  )
	  (if (and (< (/ pi 2.) ang) (<= ang (/ (* 3. pi) 2.)))
		(setq ang (- ang pi))
	  )
	  (setq point (trans point 0 norm))
	  (entmakex
		(list
		  (cons 0 "TEXT")
		  (cons 7  (getvar 'TEXTSTYLE))
		  (cons 40 (getvar 'TEXTSIZE))
		  (cons 10 point)
		  (cons 11 point)
		  (cons 1 (cdr (assoc 8 (entget entity))))
		  (cons 50 ang)
		  (cons 72 1)
		  (cons 73 2)
		  (cons 210 norm)
		)
	  )
	[color="red"](command "_.trim" (entlast) "" point "" )[/color]
	)
  )
  

   )
 (princ)
)

Link to comment
Share on other sites

Hi LISP2LEARN,

 

Quick Tip: Code is formatted better in forum posts if you don't use Tabs - if you are using the VLIDE to write your code, this option can be set under:

 

Tools > Environment Options > Visual LISP Format Options > [uncheck] Insert Tabs

 

Supplying the text insertion point to the Trim command would, in most cases, select and attempt to trim the text object (which is invalid), so, assuming I have understood the behaviour you are looking for, these would be my suggestions:

 

;;coded by Lee
(defun c:LTAG ( / ang entity norm point text ) (vl-load-com)
 (while
   (and (setq entity (entsel))
     (not
       (vl-catch-all-error-p
         (setq point
           (vl-catch-all-apply 'vlax-curve-getclosestpointto
             (list (car entity) (trans (cadr entity) 1 0))
           )
         )
       )
     )
   )
   (setq entity (car entity)
         norm   (trans '(0. 0. 1.) 1 0 t)
   )
   (setq ang
     (angle '(0. 0. 0.)
       (trans
         (vlax-curve-getfirstderiv entity
           (vlax-curve-getparamatpoint entity point)
         )
         0 norm
       )
     )
   )
   (if (and (< (/ pi 2.) ang) (<= ang (/ (* 3. pi) 2.)))
     (setq ang (- ang pi))
   )
   (setq point (trans point 0 norm))
   (if
     (setq text
       (entmakex
         (list
           (cons 0 "TEXT")
           (cons 7  (getvar 'TEXTSTYLE))
           (cons 40 (getvar 'TEXTSIZE))
           (cons 10 point)
           (cons 11 point)
           (cons 1 (cdr (assoc 8 (entget entity))))
           (cons 50 ang)
           (cons 72 1)
           (cons 73 2)
           (cons 210 norm)
         )
       )
     )
     (command "_.trim" text "" "_non" (list entity point) "")
   )
 )
 (princ)
)

 

If you have any questions about my modifications, or indeed, about any other part of the code, please do ask.

Link to comment
Share on other sites

Sorry about the formatting, I use Notepad++. I know that vlide is good but I still prefer notepad++ because I'm still in the process of learning and the split window and tabs are the one that I'm after so I don't use vlide yet.

 

Hi LISP2LEARN,

 

Quick Tip: Code is formatted better in forum posts if you don't use Tabs - if you are using the VLIDE to write your code, this option can be set under:

 

Tools > Environment Options > Visual LISP Format Options > [uncheck] Insert Tabs

 

 

Oh, I have a lot of questions but I'll leave that for now. Lee, you're a big help for beginners like us and also Renderman, Tharwat and Alan just to name a few. Thank you guys and hope you don't get tired in helping us.

 

If you have any questions about my modifications, or indeed, about any other part of the code, please do ask.
Link to comment
Share on other sites

Sorry about the formatting, I use Notepad++. I know that vlide is good but I still prefer notepad++ because I'm still in the process of learning and the split window and tabs are the one that I'm after so I don't use vlide yet.

 

No worries, I also use Notepad++ for my HTML/CSS work, this also offers the option to use spaces instead of tabs if you go to:

 

Settings > Preferences > Language Menu/Tab Settings > [Tick] Replace by Space

 

Oh, I have a lot of questions but I'll leave that for now. Lee, you're a big help for beginners like us and also Renderman, Tharwat and Alan just to name a few. Thank you guys and hope you don't get tired in helping us.

 

Thanks LISP2LEARN, I'm glad I can help :) Don't worry about asking too many questions, I welcome all questions, now matter how novice they may seem! Our time here is voluntary, so if we didn't enjoy answering questions we'd all have left some time ago :wink: Ask away!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...