Author Topic: Dynamic Block Insertion For Contour Label Orientation ???  (Read 3196 times)

0 Members and 1 Guest are viewing this topic.

ymg

  • Guest
Dynamic Block Insertion For Contour Label Orientation ???
« on: July 29, 2013, 01:30:36 AM »
Here is a quick and dirty piece of code to label contour.

It makes use of of dynamic block elv that you can find in attached drawing.

I would like this block to keep a readable orientation.  Meaning no upside down
text and keeping sideway or near vertical text always in same orientation.

I am not too good with these constraint,  could anybody help?

Code: [Select]
;; lbl by ymg                                                                                       
;;                                                                                                 
;; Insert Dynamic Block "elv" along a polyline.                                                     
;; Modified from a post by cab                                                                                                 

(defun c:lbl (/ )
    (if (setq i 0
      s (ssget '((0 . "LWPOLYLINE")
(8 . "Contour Major")
)
)       
)     
        (progn
    (command "._Undo" "_begin")
            (repeat (sslength s)
        (setq ent (ssname s i)
                        i (1+ i)
        )

        (setvar "CLAYER" "Contour Label")       
     
                (setq  spacing  500
                           len (vlax-curve-getdistatparam ent (vlax-curve-getendparam ent))
                  tspc (/ spc 2)
                )
     
     
        (while (< tspc len)
            (command "-insert" "elv" "_near" (vlax-curve-getpointatdist ent tspc) "1" "" "")
                    (setq tspc (+ tspc spc))
                )
     
    );end repeat
 
            (command "._Undo" "_end")
); end progn
    );end if  
    (princ)
)


ymg

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #1 on: July 29, 2013, 03:25:56 AM »
Try this ...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:Test (/ *error* i s ent spc n c cm r d p)
  2. ;;;     Tharwat 29.07.2013      ;;;
  3.   (or doc
  4.   )
  5.   (defun *error* (x)
  6.     (if cm
  7.       (mapcar 'setvar
  8.               '(cmdecho attreq attdia clayer)
  9.               (list cm r d c)
  10.       )
  11.     )
  12.     (if doc
  13.       (vla-endundomark doc)
  14.     )
  15.     (princ "\n*Cancel*")
  16.   )
  17.   (if
  18.     (and (if (not (tblsearch "LAYER" "Contour Label"))
  19.            (progn
  20.              (alert "Layer < Contour Label > is not found in drawing !!")
  21.              nil
  22.            )
  23.            t
  24.          )
  25.          (setq s (ssget '((0 . "LWPOLYLINE")
  26.                           (8 . "Contour Major")
  27.                          )
  28.                  )
  29.          )
  30.     )
  31.      (progn
  32.        (setq c  (getvar 'clayer)
  33.              r  (getvar 'attreq)
  34.              d  (getvar 'attdia)
  35.              cm (getvar 'cmdecho)
  36.        )
  37.        (mapcar 'setvar
  38.                '(cmdecho attreq attdia clayer)
  39.                (list 0 1 0 "Contour Label")
  40.        )
  41.        (vla-startUndoMark doc)
  42.        (repeat (setq i (sslength s))
  43.          (setq ent (ssname s (setq i (1- i))))
  44.          (setq spc 500.
  45.                n   spc
  46.          )
  47.          (while (setq p (vlax-curve-getpointatdist ent spc))
  48.            (command "_.-insert" "elv" "_non" p "1" "0")
  49.            (setq spc (+ n spc))
  50.          )
  51.        )
  52.        (mapcar 'setvar
  53.                '(cmdecho attreq attdia clayer)
  54.                (list cm r d c)
  55.        )
  56.        (vla-endundomark doc)
  57.      )
  58.   )
  59.   (princ)
  60. )
  61.  

ymg

  • Guest
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #2 on: July 29, 2013, 08:38:13 AM »
Tharwat,

This gives me label always horizontal.

What I am after is the label should be tangent to the contour, but the attribute should
never align in the (180 --> 90 )  or the (360-->180).  When we are in this range the
label should be flipped by 180 degrees.

Thanks,

ymg

ymg

  • Guest
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #3 on: July 29, 2013, 06:06:09 PM »
Code below does it !

Any smarter way ?

I would think that with proper constraint on the block,
we could do without creating the second point on the curve
to get the direction of the label.

So contrary to what I stated in previous post the rotation
parameter must not be between  90 and 270.
In that case we flip by 180 degrees.

Code - Auto/Visual Lisp: [Select]
  1.  
  2. ;;;     Tharwat 29.07.2013      ;;;
  3. ;;; Modified ymg                ;;;
  4.  
  5. (defun c:lbl (/ *error* i s ent spc n c cm r d p)
  6.  
  7.   (or doc
  8.   )
  9.  
  10.   (defun *error* (x)
  11.      (if cm
  12.         (mapcar 'setvar
  13.                     '(cmdecho attreq attdia clayer)
  14.                     (list cm r d c)
  15.         )
  16.      )
  17.      (if doc (vla-endundomark doc))
  18.      (princ "\n*Cancel*")
  19.   )
  20.  
  21.   (if (and (if (not (tblsearch "LAYER" "Contour Label"))
  22.               (progn
  23.                   (alert "Layer < Contour Label > is not found in drawing !!")
  24.                    nil
  25.               )
  26.               t
  27.            )
  28.            (setq s (ssget '((0 . "LWPOLYLINE")
  29.                             (8 . "Contour Major")
  30.                            )
  31.                    )
  32.            )
  33.       )
  34.       (progn
  35.           (setq c (getvar 'clayer)
  36.                 r (getvar 'attreq)
  37.                 d (getvar 'attdia)
  38.                cm (getvar 'cmdecho)
  39.           )
  40.  
  41.           (mapcar 'setvar
  42.                      '(cmdecho attdia attreq clayer)
  43.                      (list 0 1 0 "Contour Label")
  44.           )
  45.  
  46.           (vla-startUndoMark doc)
  47.  
  48.           (setq spacing 500)
  49.           (repeat (setq i (sslength s))
  50.               (setq ent (ssname s (setq i (1- i)))
  51.                     start (/ spacing 2)
  52.               )
  53.               (while (setq p (vlax-curve-getpointatdist ent start))
  54.                  (setq p1 (vlax-curve-getpointatdist ent (- start 10))
  55.                        rot (rtd (angle p1 p))
  56.                  )
  57.                  
  58.                  (cond
  59.                      ((< 90 rot 270) (setq rot (+ rot 180)))
  60.                  )
  61.                  
  62.                  (command "_.-insert" "elv" "_non" p "1" rot)
  63.                  (setq start (+ start spacing))
  64.               )
  65.           )
  66.           (mapcar 'setvar
  67.                      '(cmdecho attreq attdia clayer)
  68.                      (list cm r d c)
  69.           )
  70.           (vla-endundomark doc)
  71.      )
  72.   )
  73.   (princ)
  74. )
  75. (defun rtd (a) (* 180.0 (/ a pi)))
  76.  


ymg

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #4 on: July 29, 2013, 07:04:48 PM »
You could use this to get the rotation angle and only need 1 point.

Never mind upon testing results are erratic....
« Last Edit: July 29, 2013, 07:36:15 PM by snownut2 »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #5 on: July 30, 2013, 07:22:14 AM »
This is the function that I use regularly for this purpose:
Code - Auto/Visual Lisp: [Select]
  1. ;; Make Readable  -  Lee Mac
  2. ;; Returns a given angle corrected for text readability
  3.  
  4. (defun LM:MakeReadable ( a )
  5.     (   (lambda ( a ) (if (and (< (* pi 0.5) a) (<= a (* pi 1.5))) (+ a pi) a))
  6.         (rem (+ a pi pi) (+ pi pi))
  7.     )
  8. )

You could use it in the following way:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:lbl ( / blk bln dis ent idx inc ins sel spc )
  2.     (setq bln "Contour Label") ;; Block name
  3.     (cond
  4.         (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer))))))
  5.             (princ "\nCurrent layer locked.")
  6.         )
  7.         (   (not
  8.                 (or (tblsearch "block" (setq blk bln))
  9.                     (setq blk (findfile (strcat bln ".dwg")))
  10.                 )
  11.             )
  12.             (princ (strcat "\n" bln " block not found."))
  13.         )
  14.         (   (setq sel (ssget '((0 . "LWPOLYLINE") (8 . "Contour Major"))))
  15.             (setq spc (vlax-get-property (vla-get-activedocument (vlax-get-acad-object)) (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
  16.                   dis 500.0
  17.             )
  18.             (repeat (setq idx (sslength sel))
  19.                 (setq ent (ssname sel (setq idx (1- idx)))
  20.                       inc (- (/ dis 2.0) dis)
  21.                 )
  22.                 (while (setq ins (vlax-curve-getpointatdist ent (setq inc (+ inc dis))))
  23.                     (vla-insertblock spc (vlax-3D-point ins) blk 1.0 1.0 1.0
  24.                         (LM:makereadable (angle '(0.0 0.0) (trans (vlax-curve-getfirstderiv ent (vlax-curve-getparamatpoint ent ins)) 0 1)))
  25.                     )
  26.                 )
  27.             )
  28.         )
  29.     )
  30.     (princ)
  31. )
  32.  
  33. ;; Make Readable  -  Lee Mac
  34. ;; Returns a given angle corrected for text readability
  35.  
  36. (defun LM:MakeReadable ( a )
  37.     (   (lambda ( a ) (if (and (< (* pi 0.5) a) (<= a (* pi 1.5))) (+ a pi) a))
  38.         (rem (+ a pi pi) (+ pi pi))
  39.     )
  40. )

Note that the above code is untested!

ymg

  • Guest
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #6 on: July 30, 2013, 02:29:21 PM »
Quote
This is the function that I use regularly for this purpose

Thanks Lee,

Would this be equivalent ?

Code - Auto/Visual Lisp: [Select]
  1. (rem (cond ((< (* pi 0.5) a (* pi 1.5))(+ a pi))(t a))(+ pi pi))

I like your example function and getting rid of the "command" with vla-insertblock.

I did look into the first derivative but could not get it to work. You've shown me!

ymg


Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Dynamic Block Insertion For Contour Label Orientation ???
« Reply #7 on: July 30, 2013, 06:04:39 PM »
Would this be equivalent ?
Code - Auto/Visual Lisp: [Select]
  1. (rem (cond ((< (* pi 0.5) a (* pi 1.5))(+ a pi))(t a))(+ pi pi))

No, since my function accounts for any arguments -2π ≤ a, whereas your version will perform incorrectly for supplied angles outside the range 0 ≤ a ≤ 2π

I like your example function and getting rid of the "command" with vla-insertblock.

I did look into the first derivative but could not get it to work. You've shown me!

You're welcome!  :-)