Author Topic: help - align texts  (Read 1828 times)

0 Members and 1 Guest are viewing this topic.

Fabricio28

  • Swamp Rat
  • Posts: 670
help - align texts
« on: January 25, 2013, 12:03:15 PM »
Hi, guys
I have to align multiple texts to a polyline. And I've found a great lisp from Mark S. Thomas.
But the problem the code allow selection just a single text.

Can anybody help me add, "selection multiple texts" in this code, please?

I wish this lisp had 2 options: single and multiple.

Thank in advance.


Code: [Select]
(defun c:rrt (/
               ; local functions
               getSegment get-opp-ang undobegin undoend
               ; local variables
               ent txt_ent obj txt_obj obj_typ ang ans
               )

  ;;; FUNCTION
  ;;; rotates the user selected (M)TEXT to the user selected
  ;;; entity. valid entites are light weight plines, lines
  ;;; and (m)text. you are given the chance to rotate the
  ;;; by 180 degrees after intial rotation.
  ;;;
  ;;; ARGUMENTS
  ;;; none
  ;;;
  ;;; USAGE
  ;;; enter RRT on the comand line
  ;;;
  ;;; PLATFORMS
  ;;; 2000+
  ;;;
  ;;; AUTHOR
  ;;; Copyright© 2004 Mark S. Thomas
  ;;; mark_AT_theswamp.org
  ;;;
  ;;; VERSION
  ;;; 1.0 Tue Dec 07, 2004
  ;;; 1.1 Tue Dec 21, 2004 ; added ARC types
  ;;; 1.1a Tue Dec 21, 2004 ; reversed the pick order
  ;;;
  ;;; TODO:
  ;;; handle text that has 'fit' justification
  ;;; add more entites for angle extraction
  ;;; more testing

  (vl-load-com)

  ;; credit Stig Madsen
  ;; refer to thread titled "relaxed-curves" under the "Teach Me"
  ;; section of TheSwamp at www.theswamp.org/phpBB2/
  (defun getSegment (obj pt / cpt eParam stParam)
    (cond ((setq cpt (vlax-curve-getClosestPointTo obj pt))
           (setq eParam (fix (vlax-curve-getEndParam obj)))
           (if (= eParam (setq stParam (fix (vlax-curve-getParamAtPoint obj cpt))))
             (setq stParam (1- stParam))
             (setq eParam (1+ stParam))
             )
           (list eParam (vlax-curve-getPointAtParam obj stParam)
                 (vlax-curve-getPointAtParam obj eParam))
           )
          )
    )

  ;; undo functions
  (defun undobegin ()
    (vla-EndUndoMark
      (vlax-get-property
        (vlax-get-acad-object)
        'ActiveDocument
        )
      )
    (vla-StartUndoMark
      (vlax-get-property
        (vlax-get-acad-object)
        'ActiveDocument
        )
      )
    )

  (defun undoend ()
    (vla-EndUndoMark
      (vlax-get-property
        (vlax-get-acad-object)
        'ActiveDocument
        )
      )
    )

  ;; returns the oppsite of an angle define in radians
  (defun get-opp-ang (ang)
    (cond ((< ang pi)(+ ang pi))
          ((> ang pi)(- ang pi))
          ((equal ang pi) 0.0)
          ((equal ang 0.0) pi)
          )
    )

  ;; ================= body of main function starts here ======================
 
  ;;  -----------   Get the Text to Align  -----------------
  (cond
    ((setq txt_ent (car (entsel "\nSelect text to align")))
     (setq txt_obj (vlax-ename->vla-object txt_ent)
           obj_typ (vlax-get-property txt_obj 'ObjectName)
           )
     (cond
       ((or (= obj_typ "AcDbMText") (= obj_typ "AcDbText")))
       (T
         (setq txt_ent nil)
         (alert "I only know how to align (M)TEXT, sorry! "))
      )
    )
  )
 
  ;;  -----------   Get the Object to Align To  -----------------
  (cond
    ((and txt_ent
          (setq ent (entsel "\nSelect entity for alignment: ")))
       (setq obj (vlax-ename->vla-object (car ent))
             obj_typ (vlax-get-property obj 'ObjectName)
       )
       (cond
         ((= obj_typ "AcDbPolyline")
          (if (setq pt_lst (getSegment obj (last ent)))
            (setq ang (angle (cadr pt_lst)(caddr pt_lst)))
            )
          )
         ((= obj_typ "AcDbLine")
          (setq ang (vlax-get-property obj 'Angle))
          )
         ((= obj_typ "AcDbText")
          (setq ang (vlax-get-property obj 'Rotation))
          )
         ((= obj_typ "AcDbMText")
          (setq ang (vlax-get-property obj 'Rotation))
          )
         ((= obj_typ "AcDbArc")
          (setq ang (angle
                      (vlax-safearray->list
                        (vlax-variant-value
                          (vla-get-StartPoint obj)))
                      (vlax-safearray->list
                        (vlax-variant-value
                          (vla-get-EndPoint obj)))
                    )
           )
          )
         
         (T (alert "That's not an entity I deal with"))
       )
     )
  )
 
  ;;  -----------   Align the Text   -----------------
  (cond
    ((null ang)) ; do nothing
    ((null txt_ent)) ; do nothing
    (T
      (undobegin)
      (vlax-put-property txt_obj 'Rotation ang)
      (setq ans (getstring "\nRotate 180 [Y/N]<N>: "))
      (if (= (strcase ans) "Y")
        (vlax-put-property txt_obj 'Rotation (get-opp-ang ang))
        )
      (vlax-release-object txt_obj)
      (undoend)
     )
   )
  (princ)
)
« Last Edit: January 25, 2013, 12:42:07 PM by FABRICIO28 »

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: help - align texts
« Reply #1 on: January 25, 2013, 03:04:47 PM »
Hi Billy  :-)

Why don't you upload an image or a drawing that explains the issue which is better for all to know the aim of your needs ?

Regards

Fabricio28

  • Swamp Rat
  • Posts: 670
Re: help - align texts
« Reply #2 on: January 25, 2013, 08:22:36 PM »
Hi my friend Tharwat.
How are you?

Sorry  for my poor english. Maybe a file could explain better my task.

I have to align a lot of texts like a polyline. But the rrt.lsp allow me select one at the time and I'd would like select multiple texts.

Sincerely yours,
Billy
 :-D


Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: help - align texts
« Reply #3 on: January 26, 2013, 02:00:18 AM »
Hi Billy .

Try the following code and if you had a strange rotation of texts , that should be related to the angle of the selected polyline' s start and
end points , so reverse the polyline and try again .

Code - Auto/Visual Lisp: [Select]
  1. (defun c:Test (/ e ss sel i e ang pt)
  2.   (if
  3.     (and (progn
  4.            (prompt "\n Select single polyline ..")
  5.            (setq ss (ssget "_+.:E:S" '((0 . "*POLYLINE"))))
  6.          )
  7.          (if (not
  8.                (eq (1+ (fix (vlax-curve-getendparam (ssname ss 0)))) 2)
  9.              )
  10.            (progn
  11.              (princ "\n Polyline has more than two points !!")
  12.              nil
  13.            )
  14.            (setq pt (mapcar 'cdr
  15.                             (vl-remove-if-not
  16.                               '(lambda (x) (eq (car x) 10))
  17.                               (entget (ssname ss 0))
  18.                             )
  19.                     )
  20.            )
  21.          )
  22.          (progn
  23.            (prompt "\n Select Texts to rotate ...")
  24.            (setq sel (ssget "_:L" '((0 . "*TEXT"))))
  25.          )
  26.     )
  27.      (repeat (setq i (sslength sel))
  28.        (setq e   (entget (ssname sel (setq i (1- i))))
  29.              ang (angle (car pt) (cadr pt))
  30.        )
  31.        (entmod
  32.          (subst (cons 50
  33.                       (if (and (< (* 0.5 pi) ang) (<= ang (* 1.5 pi)))
  34.                         (setq ang (+ pi ang))
  35.                         ang
  36.                       )
  37.                 )
  38.                 (assoc 50 e)
  39.                 e
  40.          )
  41.        )
  42.      )
  43.      (princ)
  44.   )
  45.   (princ)
  46. )
  47.  
« Last Edit: January 26, 2013, 09:44:50 AM by Tharwat »

pBe

  • Bull Frog
  • Posts: 402
Re: help - align texts
« Reply #4 on: January 26, 2013, 05:41:35 AM »
Code: [Select]
(prompt "\n Select single polyline ..")nil

Code: [Select]
(princ "\n Select single polyline ..")


Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: help - align texts
« Reply #5 on: January 26, 2013, 05:47:20 AM »
Thanks pBe ,  :-)

I have forgotten to add the progn function .

Fabricio28

  • Swamp Rat
  • Posts: 670
Re: help - align texts
« Reply #6 on: January 26, 2013, 06:41:33 AM »
Hi Billy .

Try the following code and if you had a strange rotation of texts , that should be related to the angle of the selected polyline' s start and
end points , so reverse the polyline and try again .

Hi Tharwart,
Perfect! :-D

Can I request just one more thing for the code?
"selected polyline' s start and end points".
Perharps if you add rotate 180° after the routine, the problem is solved.
e.g.(getstring "\nRotate 180 [Y/N]<N>: "))

Thank you for the help.

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: help - align texts
« Reply #7 on: January 26, 2013, 07:02:05 AM »
Here is an alternative:

Code: [Select]
(defun c:at ( / a e i p s )
    (if (setq s (LM:ssget "\nSelect Text: " '("_:L" ((0 . "*TEXT")))))
        (progn
            (while
                (progn (setvar 'errno 0) (setq e (entsel))
                    (cond
                        (   (= 7 (getvar 'errno))
                            (princ "\nMissed, try again.")
                        )
                        (   (= 'ename (type (car e)))
                            (if
                                (vl-catch-all-error-p
                                    (setq p
                                        (vl-catch-all-apply 'vlax-curve-getclosestpointto
                                            (list (car e) (trans (cadr e) 1 0))
                                        )
                                    )
                                )
                                (princ "\nInvalid object selected.")
                            )
                        )
                    )
                )
            )
            (if (= 'ename (type (setq e (car e))))
                (progn
                    (setq a (angle '(0.0 0.0) (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e p))))
                    (if (and (< (* 0.5 pi) a) (<= a (* 1.5 pi)))
                        (setq a (+ pi a))
                    )
                    (repeat (setq i (sslength s))
                        (setq e (entget (ssname s (setq i (1- i)))))
                        (entmod (subst (cons 50 a) (assoc 50 e) e))
                    )
                )
            )
        )
    )
    (princ)
)

;; ssget  -  Lee Mac
;; A wrapper for the ssget function to permit the use of a custom selection prompt
;;
;; Arguments:
;; msg    - selection prompt
;; params - list of ssget arguments

(defun LM:ssget ( msg params / sel )
    (princ msg)
    (setvar 'nomutt 1)
    (setq sel (vl-catch-all-apply 'ssget params))
    (setvar 'nomutt 0)
    (if (not (vl-catch-all-error-p sel)) sel)
)
(vl-load-com)
(princ)

The above uses the direction of the first derivative of the curve at the point of selection, resulting in compatibility with all curve objects (not solely LWPolylines), and will also correct the angle to retain the 'readability' of the text.

Fabricio28

  • Swamp Rat
  • Posts: 670
Re: help - align texts
« Reply #8 on: January 26, 2013, 07:55:21 AM »
Hi Lee,
Excellent code, worked like a charm, I really appreciate your help.

Many Thanks!

@Thawart
Thank you very much too.

Kind Regards
 :-D

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: help - align texts
« Reply #9 on: January 26, 2013, 09:48:47 AM »
@Thawart
Thank you very much too.

Kind Regards
 :-D

You're  welcome Billy , codes updated as lee stated the angle in his own codes  ^-^