Insert text in line and break problem

Discussion in 'AutoCAD' started by John Crocco, Feb 20, 2004.

  1. John Crocco

    John Crocco Guest

    I currently am able to do this, but wanted to go one a step farther and
    break the line based on the text inserted.

    Right now, it is a predetermined space that the line is broken and the text
    inserted in, but if the text is longer or too short for the break, the lines
    need to be adjusted manually.

    Is there a way to assign a distance for characters typed so it would break
    the line based on the text string length?

    Currently, my lisp asks for a point on a horizontal line (have another for
    vertical to make a one pick lisp) and it breaks the line a predetermined
    distance, inserts a text block in the middle, and brings up the text editor
    to edit the text being inserted.

    I would like to pick the point, type in the text, and have the program
    determine the break line distance based on text string and break line
    accordingly.

    Any ideas?
     
    John Crocco, Feb 20, 2004
    #1
  2. John Crocco

    Jeff Mishler Guest

    Here are some hints.....
    get & save rotation angle
    change rotation angle to zero
    get the bounding box
    increase length derived from bounding box by the dimgap variable * dimscale
    put rotation angle back to original

    If this doesn't get you going, ask again and I'll share some code....

    Jeff
     
    Jeff Mishler, Feb 20, 2004
    #2
  3. John Crocco

    John Crocco Guest

    I dont understand the bounding box, aint that used for 3d?

    BTW, here my code thus far: It is very simple, but it does work.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;Custom commands by John Crocco
    ;breaks horizontal line and inserts STARBUCK text, exploded for editing.
    (DEFUN C:starH (/ pt1 pt2 len os sc *Error*)
    ;;;;;;;;; Application error handler
    (defun *Error* (Msg)
    (command "._Undo" "_End") ; end undo group
    (cond
    ((not Msg)) ; no error, do nothing
    ((member (strcase Msg T) ; cancel, do undo
    '("console break"
    "function cancelled"
    "quit / exit abort"))
    (command "._U")
    (setvar "cmdecho" cecho)
    (command "osmode" os);UNDO COMMANDS HERE
    ;
    ;
    ;
    );END OF MEMBER
    ((princ (strcat "\nError: " Msg)))
    ) ; END OF COND
    (princ)
    ); END OF DEFUN ERROR
    (setq cecho (getvar "cmdecho"))
    (setvar "CmdEcho" 0) ; turn echo off
    (command "._Undo" "_End") ; close any open group
    (command "._Undo" "_BEgin") ; start new group
    ;;;;;;;;;;;;;;;;;;;;;;
    (setq os (getvar "osmode"))
    (command "osmode" "512")
    (setq pt1 (getpoint "\nInsertion Point: "))
    (setq sc (getvar "userr1"))
    (setq pt2 (* 100.0 sc))
    (setq len (polar pt1 0.0 pt2))
    (command "BREAK" pt1 len)
    (command "INSERT" "*starbucktextH" pt1 sc sc)
    (command "ddedit" (entlast) "")
    (command "osmode" os)
    (setvar "cmdecho" cecho)
    (*Error* nil) ;call error handler w/no error
    )
     
    John Crocco, Feb 20, 2004
    #3
  4. John Crocco

    Jeff Mishler Guest

    John,
    Using ActiveX, all entities have a bounding box. In this case, text has a
    lower left and upper right in the x/y format. Since it is true x/y, that is
    why we must first place the text at 0 degrees rotation.
    Add the followng to your code, immediately following the error definition:

    (defun breakline ( / rot ent ll ur len brkpt1 brkpt2)
    (vl-load-com)
    (setq ent (vlax-ename->vla-object (entlast))
    rot (vla-get-rotation ent))
    (vla-put-rotation ent 0)
    (vla-getboundingbox ent 'll 'ur)
    (vla-put-rotation ent rot)
    (vla-put-visible ent :vlax-false); to ensure line is selected in break
    (setq ll (vlax-safearray->list ll)
    ur (vlax-safearray->list ur)
    len (+ (- (car ur) (car ll)) (* 2 (* sc (getvar "dimgap"))))
    brkpt1 (polar pt1 rot (- (* sc (getvar "dimgap"))))
    brkpt2 (polar brkpt1 rot len))
    (command "_.BREAK" brkpt1 brkpt2)
    (vla-put-visible ent :vlax-true)
    )

    Then, change this part of your code:

    (setq sc (getvar "userr1"))
    ;;; (setq pt2 (* 100.0 sc))
    ;;; (setq len (polar pt1 0.0 pt2))
    ;;; (command "BREAK" pt1 len)
    (command "INSERT" "*starbucktextH" pt1 sc 0);changed last sc to 0, it's
    the rotation
    (command "ddedit" (entlast) "")
    (breakline)
    (command "osmode" os)

    HTH,
    Jeff
     
    Jeff Mishler, Feb 20, 2004
    #4
  5. John Crocco

    John Crocco Guest

    Thank you Jeff, this works pretty good, as I dont know or understand fully
    the VL commands yet.

    However, The insertion isnt correct anymore. In breakline, you make a
    brkpt1 and brkpt2. If I can get the midpoint of these two points, and use
    that as the insertion point, it would work. Will the value be carried down
    out of the breakline command, or can I define the midpoint of brkpt1 brkpt2
    outside of the breakline command?
     
    John Crocco, Feb 20, 2004
    #5
  6. John Crocco

    John Crocco Guest

    I modified it as below, but doesnt work. It seems I need to define the
    distance, before inserting the text, but the break command is after
    inserting the text, which I need to do to get the distance for the insertion
    point.

    Kinda in a circle here right? Is there another way?

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;Custom commands by John Crocco
    ;breaks horizontal line and inserts STARBUCK text, exploded for editing.
    (DEFUN C:testbreak (/ pt1 pt2 pt3 len os dist sc *Error*)
    ;;;;;;;;; Application error handler
    (defun *Error* (Msg)
    (command "._Undo" "_End") ; end undo group
    (cond
    ((not Msg)) ; no error, do nothing
    ((member (strcase Msg T) ; cancel, do undo
    '("console break"
    "function cancelled"
    "quit / exit abort"))
    (command "._U")
    (setvar "cmdecho" cecho)
    (command "osmode" os);UNDO COMMANDS HERE
    ;
    ;
    ;
    );END OF MEMBER
    ((princ (strcat "\nError: " Msg)))
    ) ; END OF COND
    (princ)
    ); END OF DEFUN ERROR
    (setq cecho (getvar "cmdecho"))
    (setvar "CmdEcho" 0) ; turn echo off
    (command "._Undo" "_End") ; close any open group
    (command "._Undo" "_BEgin") ; start new group
    ;;;;;;;;;;;;;;;;;;;;;;
    (defun breakline ( / rot ent ll ur len dist brkpt1 brkpt2 pt3)
    (vl-load-com)
    (setq ent (vlax-ename->vla-object (entlast))
    rot (vla-get-rotation ent))
    (vla-put-rotation ent 0)
    (vla-getboundingbox ent 'll 'ur)
    (vla-put-rotation ent rot)
    (vla-put-visible ent :vlax-false); to ensure line is selected in break
    (setq ll (vlax-safearray->list ll)
    ur (vlax-safearray->list ur)
    len (+ (- (car ur) (car ll)) (* 2 (* sc (getvar "dimgap"))))
    brkpt1 (polar pt1 rot (- (* sc (getvar "dimgap"))))
    brkpt2 (polar brkpt1 rot len))
    (command "_.BREAK" brkpt1 brkpt2)
    (setq dist (polar brkpt1 0.0 brkpt2))
    (setq pt3 (polar prkpt1 0.0 (* 0.5 dist)))
    (vla-put-visible ent :vlax-true)
    )
    ;;;;;;;;;;;;;;;;;;;;;;
    (setq os (getvar "osmode"))
    (command "osmode" "512")
    (setq pt1 (getpoint "\nInsertion Point: "))
    (setq sc (getvar "userr1"))
    (command "INSERT" "*STARBUCKTEXTHtest" pt3 sc 0);last 0 is the rotation
    (command "ddedit" (entlast) "")
    (breakline)
    (command "osmode" os)
    (setvar "cmdecho" cecho)
    (*Error* nil) ;call error handler w/no error
    )
     
    John Crocco, Feb 20, 2004
    #6
  7. John Crocco

    Jeff Mishler Guest

    Sorry, John,
    I should've picked up the fact that your text is a middle insert......here's
    a revised one that works with middle aligned text.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;Custom commands by John Crocco
    ;breaks horizontal line and inserts STARBUCK text, exploded for editing.
    (defun c:starh (/ pt1 pt2 len os sc *error*)
    ;;;;;;;;; Application error handler
    (defun *error* (msg)
    (command "._Undo" "_End") ; end undo group
    (cond
    ((not msg)) ; no error, do nothing
    ((member (strcase msg t) ; cancel, do undo
    '("console break"
    "function cancelled"
    "quit / exit abort"
    )
    )
    (command "._U")
    (setvar "cmdecho" cecho)
    (command "osmode" os) ;UNDO COMMANDS HERE
    ;
    ;
    ;
    ) ;END OF MEMBER
    ((princ (strcat "\nError: " msg)))
    ) ; END OF COND
    (princ)
    ) ; END OF DEFUN ERROR
    (setq cecho (getvar "cmdecho"))
    (setvar "CmdEcho" 0) ; turn echo off
    (command "._Undo" "_End") ; close any open group
    (command "._Undo" "_BEgin") ; start new group
    ;;;;;;;;;;;;;;;;;;;;;;
    (defun breakline ()
    (vl-load-com)
    (setq ent (vlax-ename->vla-object (entlast))
    rot (vla-get-rotation ent))
    (vla-put-rotation ent 0)
    (vla-getboundingbox ent 'll 'ur)
    (vla-put-rotation ent rot)
    (vla-put-visible ent :vlax-false); to ensure line is selected in break
    (setq ll (vlax-safearray->list ll)
    ur (vlax-safearray->list ur)
    len (+ (- (car ur) (car ll))
    (* 2 (* (getvar "dimscale") (getvar "dimgap"))))
    brkpt1 (polar pt1 rot (- (/ len 2)))
    brkpt2 (polar brkpt1 rot len))
    (command "_.BREAK" brkpt1 brkpt2)
    (vla-put-visible ent :vlax-true)
    )
    (setq os (getvar "osmode"))
    (command "osmode" "512")
    (setq pt1 (getpoint "\nInsertion Point: "))
    (setq sc (getvar "userr1"))
    ;;; (setq pt2 (* 100.0 sc))
    ;;; (setq len (polar pt1 0.0 pt2))
    ;;; (command "BREAK" pt1 len)
    (command "INSERT" "*starbucktextH" pt1 sc 0)
    (command "ddedit" (entlast) "")
    (breakline)
    (command "osmode" os)
    (setvar "cmdecho" cecho)
    (*error* nil) ;call error handler w/no error
    )
     
    Jeff Mishler, Feb 20, 2004
    #7
  8. John Crocco

    John Crocco Guest

    Jeff, MY MAN thanks works great. Trying to see how you did that to learn,
    thank you.
    ONE other thing, It works too good!!! the line is exactly touching the text.
    Is there a way to add 1 or 2 spaces to the overal length or size so that the
    break is a little bigger, or add a set value say (* 2 sc) to the distance?
    Let me know if you could.

    thanks
     
    John Crocco, Feb 20, 2004
    #8
  9. John Crocco

    Jeff Mishler Guest

    Actually, I was using the "text offset from dimension line" variable to calc
    the length of the break. But if that is set for a different scale, then it
    won't give the desired result. Try changing the line for setq'ing the len
    from:
    len (+ (- (car ur) (car ll))
    (* 2 (* (getvar "dimscale") (getvar "dimgap"))))
    to this:
    len (+ (- (car ur) (car ll))
    (getvar "textsize"))

    That will place the break at 1/2 the height of the text each direction.

    If you have any specific questions as to what does what & where.......just
    ask.

    Jeff
     
    Jeff Mishler, Feb 20, 2004
    #9
  10. John Crocco

    John Crocco Guest

    Jeff, thanks again. I still have a hard time learning the "NEW" lisp. I
    cant seem to figure out how you would make this into a vertical break as
    well, since you change it to zero. would it need to change it to 0,
    determine the length, then rotate it 90 and do break in that direction?
     
    John Crocco, Feb 24, 2004
    #10
  11. John Crocco

    Jeff Mishler Guest

    John,
    I know how you feel about the new lisp.....I was there not too long ago
    myself.

    I've modified your routine so you don't need 2 seperate ones for different
    angles. This will work on ANY line and will also make the text "plan
    readable". In other words, the text will only be inserted with a rotation
    angle between +90 degrees and -89.9 degrees. If a line is drawn at 270
    degrees (start point has a larger y value than the end point), the routine
    will still place the text with a 90 degree rotation.

    I've also commented it so you can see, hopefully, what I've done.

    On another note, instead of placing an exploded block, why not just create
    the text in the routine? That way you never need to worry about the block
    being available.

    Jeff

    p.s. Watch for Word wrap......

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;Custom commands by John Crocco
    ;breaks line and inserts STARBUCK text, exploded for editing.
    (defun c:starh (/ pt1 pt2 len os sc *error*)
    ;;;;;;;;; Application error handler
    (defun *error* (msg)
    (command "._Undo" "_End") ; end undo group
    (cond
    ((not msg)) ; no error, do nothing
    ((member (strcase msg t) ; cancel, do undo
    '("console break"
    "function cancelled"
    "quit / exit abort"
    )
    )
    (command "._U")
    (setvar "cmdecho" cecho)
    (command "osmode" os) ;UNDO COMMANDS HERE
    ;
    ;
    ;
    ) ;END OF MEMBER
    ((princ (strcat "\nError: " msg)))
    ) ; END OF COND
    (princ)
    ) ; END OF DEFUN ERROR
    (vl-load-com)
    (setq cecho (getvar "cmdecho"))
    (setvar "CmdEcho" 0) ; turn echo off
    (command "._Undo" "_End") ; close any open group
    (command "._Undo" "_BEgin") ; start new group
    ;;;;;;;;;;;;;;;;;;;;;;
    (defun breakline ()
    (setq ent (vlax-ename->vla-object (entlast));get the new text entity
    rot (vla-get-rotation ent));get the text rotation
    (vla-put-rotation ent 0);set rotation to 0 for bounding box extraction
    (vla-getboundingbox ent 'll 'ur);sets vars ll & ur to the lower left and
    ;upper right corners of bounding box
    (vla-put-rotation ent rot);put the text back to correct rotation
    (vla-put-visible ent :vlax-false); to ensure line is selected in break
    (setq ll (vlax-safearray->list ll);converts to coordinate list
    ur (vlax-safearray->list ur);converts to coordinate list
    len (+ (- (car ur) (car ll));len is x2 - x1
    (getvar "textsize"));make length longer by textsize value
    brkpt1 (polar pt1 rot (- (/ len 2)))
    brkpt2 (polar brkpt1 rot len))
    (command "_.BREAK" brkpt1 brkpt2)
    (vla-put-visible ent :vlax-true)
    )
    (setq os (getvar "osmode"))
    ;(setvar "USERR1" 20.0);;added for testing by jm
    (setq sc (getvar "USERR1"))
    (command "osmode" "512")
    (setq pt1 (getpoint "\nInsertion Point: "))
    (setq ent (nentselp pt1));get the entity at the point selected above
    (if (and ;test whether to continue
    ent ; is there an entity at the point?
    (setq ent
    (vlax-ename->vla-object
    (car ent))); can it be converted to vla-object?
    (= (vla-get-objectname ent) "AcDbLine"); is it a line?
    );if it passes all 3 lines, carry on.....else exit
    (progn
    (setq rot (vla-get-angle ent)); get angle of line
    (cond ((< (/ pi 2) rot (+ (* pi 1.5) 0.1))(setq rot (- rot pi))))
    ;above converts angle between 90 & 270 degrees to be "plan readable"
    ;insert block using rotation calc'd above
    (command "INSERT" "*starbucktextH" pt1 sc (angtos rot))
    (command "ddedit" (entlast) "")
    (breakline);go to breakline routine
    )
    )
    (command "osmode" os)
    (setvar "cmdecho" cecho)
    (*error* nil) ;call error handler w/no error
    )
     
    Jeff Mishler, Feb 25, 2004
    #11
  12. John Crocco

    Jeff Mishler Guest

    And I should've noted that if you select too close to the end of a line or
    if the line is too short, the routine will bomb out at the break command.
    There should be a check added for those cases, and either terminate the
    command or add a leader with the text ..... or be extremely careful ;-)

    Jeff
     
    Jeff Mishler, Feb 25, 2004
    #12
  13. John Crocco

    John Crocco Guest

    Thanks again Jeff, Were can I get the functions for this vla stuff? What is
    the term of this new lisp actually called? Is there any online
    documentation, or any in 2002 etc? It obviously has some advantages, but
    would like to know what they are and how to use them.

    I havent checked the routine yet, but I really do appreciate all your help.

    Thanks again.

    JOHN
     
    John Crocco, Feb 25, 2004
    #13
  14. John Crocco

    David Kozina Guest

    Just an idea, fwiw...

    Have you considered replacing the line with an aligned dimension? (perhaps
    one with arrowheads set to none)? I would think with all the override
    options available for dimension style creation you should be able to create
    something you like.

    You may run into some difficulties if some of the dimension endpoints are
    very close together, but I don't know how much you run into that sort of
    situation.

    One thing I really like about using dimensions is the ability to have a
    built-in 'label' ready for use, that pretty much self-adjusts if the line is
    lengthened or shortened. Plus a 'built-in' length display (that may also be
    overridden at will): <>

    Best regards,
    David Kozina
     
    David Kozina, Feb 25, 2004
    #14
  15. John Crocco

    Jeff Mishler Guest

    John,
    For some of the best info on using the ActiveX stuff with lisp, besides this
    newsgroup, is the Visual Lisp Developer's Bible by David Stein. You can
    download a copy here: www.dsxcad.com

    The help files for VBA & ActiveX are a good source, too. You just need to
    learn how to call them from lisp. One thing I've found to be extremely
    useful is the "vlax-dump-object" function. It will list what properties are
    available and, if the otional toggle is toggled, also list the methods
    applicable to an object (entity). I wrote a little routine to make it easy
    to select an entity and have it list either just the properties or the
    properties & the methods that I will share with you.

    (defun C:DUMP ( / ent obj);list properties
    (while (setq ent (entsel "\nSelect entity to get object data: "))
    (setq obj (vlax-ename->vla-object (car ent)))
    (vlax-dump-object obj)
    (vlax-release-object obj)
    (princ)
    )
    (princ)
    )

    (defun C:DUMPT ( / ent obj);list properties & methods
    (while (setq ent (entsel "\nSelect entity to get object data: "))
    (setq obj (vlax-ename->vla-object (car ent)))
    (vlax-dump-object obj T);added T to return methods available
    (vlax-release-object obj)
    (princ)
    )
    (princ)
    )

    HTH,
    Jeff
     
    Jeff Mishler, Feb 25, 2004
    #15
  16. John Crocco

    MHR Guest

    How about keeping it major simple.

    I imagine you are selecting a point on the line that represents the middle of the text? Why not use the trim command and select the text as the trim object and use the same point as the trim selection?


    (Defun C:BRK ()

    (Setq ent (Entsel "\nSelect Entity: "))
    (Setq pnt (Cadr ent))
    (Command ".TEXT" "J" "M" pnt 0.125 0 "TEST")
    (Command ".TRIM" "SI" (Entlast) ent "")

    (Princ));C:BRK
     
    MHR, Feb 25, 2004
    #16
  17. John Crocco

    MHR Guest

    Here is a variation that will follow angled lines. You can add a check for which direction the angle is and flip text 180 if necessary. I may add it in myself just to have it.

    (Defun C:BRK ()
    (Setq ent (Entsel "\nSelect Entity: "))
    (Setq txt (Getstring "\nEnter Text: "))
    (Setq pnt (Cadr ent))
    (Setq inf (Entget (Car ent)))
    (Setq p10 (Cdr (Assoc 10 inf)))
    (Setq p11 (Cdr (Assoc 11 inf)))
    (Setq ang (Angle p10 p11))
    (Setq ang (/ (* ang 180.00000000) PI))
    (Command ".TEXT" "J" "M" pnt 0.125 ang txt)
    (Command ".TRIM" "SI" (Entlast) ent "")
    (Princ));C:BRK
     
    MHR, Feb 25, 2004
    #17
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.