This lisp code has been very helpful to toggle on & off the background mask for mtext and mleaders. The only nuisance with it is this: when I use it with an multileader object, it will sometimes change the line spacing of the object to match the current value of the TSPACEFAC variable. That variable controls the line spacing for new mtext objects.
So if a mleader object has a line spacing factor of 1.5 and the current value of the variable is 1.0, when I run the command, it will sometimes adjust the object's line spacing to be 1.0.
From reading the code, I don't see where it would adjust it or be creating a new object. But I'm no expert with this stuff.
Any ideas on how to get around this? Right now it's slightly unpredictable...
Mike
;;; ------------------------------------------------------------------------ ;;; TextMaskToggle.lsp v1.2 ;;; ;;; Copyright© 03.10.09 ;;; Alan J. Thompson (alanjt) ;;; alanjt@gmail.com ;;; ;;; Permission to use, copy, modify, and distribute this software ;;; for any purpose and without fee is hereby granted, provided ;;; that the above copyright notice appears in all copies and ;;; that both that copyright notice and the limited warranty and ;;; restricted rights notice below appear in all supporting ;;; documentation. ;;; ;;; Allows user to toggle the Textmask state of selected ;;; Mtext and/or Multileaders. ;;; ;;; Revision History: ;;; ;;; v1.1 (03.16.09) Added ability to set offset (default is 1.0) ;;; v1.2 (05.25.09) Minor cosmetic changes to coding and updated ;;; subroutines. ;;; ;;; ------------------------------------------------------------------------ ;(defun c:bg (/) (c:TextmaskToggle)) (defun c:bg (/ *error* AT:SS->List AT:Undo #BackgroundOffset #SSList #Object #Ent ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;error handler (defun *error* (msg) (AT:Undo "V" "E") (if (not (member msg '("console break" "Function cancelled" "quit / exit abort") ) ;_ member ) ;_ not (princ (strcat "\nError: " msg)) ) ;_ if ) ;_ defun ;;; Convert selection set to list of ename or vla objects ;;; #Selection - SSGET selection set ;;; #VLAList - T for vla objects, nil for ename ;;; Alan J. Thompson, 04.20.09 (defun AT:SS->List (#Selection #VlaList / #List) (and #Selection (setq #List (vl-remove-if 'listp (mapcar 'cadr (ssnamex #Selection)) ) ;_ vl-remove-if ) ;_ setq (if #VlaList (setq #List (mapcar 'vlax-ename->vla-object #List)) ) ;_ if ) ;_ and #List ) ;_ defun ;;; ------------------------------------------------------------------------ ;;; AT:Undo.lsp v1.0 ;;; (SubRoutine) ;;; ;;; Copyright© 03.23.09 ;;; Alan J. Thompson (alanjt) ;;; alanjt@gmail.com ;;; ;;; Permission to use, copy, modify, and distribute this software ;;; for any purpose and without fee is hereby granted, provided ;;; that the above copyright notice appears in all copies and ;;; that both that copyright notice and the limited warranty and ;;; restricted rights notice below appear in all supporting ;;; documentation. ;;; ;;; Undo "BEGIN" and "END" options, with choice of using "COMMAND" ;;; or "VLA". User inputs coding choice (Command or VLA) and the ;;; choice to issue an 'undo begin' or 'undo end'. ;;; ;;; Arguments: ;;; #CommandVLA - Option to use command or VLA for undo marking. ;;; ("V" for VLA, "C" for Command) ;;; #BeginEnd - Option to issue an 'Undo Begin' or 'Undo End'. ;;; ("B" for Begin, "E" for End). ;;; ;;; Examples: ;;; (defun c:TEST ( / p1 p2 ) ;;; (AT:Undo "C" "B") ;;; (and ;;; (setq p1 (getpoint "\nPoint 1: ")) ;;; (setq p2 (getpoint p1 "\nPoint 2: ")) ;;; (command "_.line" p1 p2 "" ;;; "_.circle" p1 2 ;;; "_.circle" p2 2)) ;;; (AT:Undo "C" "E")) ;;; ;;; Revision History: ;;; ;;; ------------------------------------------------------------------------ (defun AT:Undo (#CommandVLA #BeginEnd / #OldCmdecho) (if (and (member (strcase #CommandVLA) (list "C" "V")) (member (strcase #BeginEnd) (list "B" "E")) ) ;_ and (cond ;; COMMAND Undo Options ((eq "C" (strcase #CommandVLA)) (setq #OldCmdecho (getvar "cmdecho")) (setvar "cmdecho" 0) (cond ;; Undo Begin ((eq "B" (strcase #BeginEnd)) (command "_.undo" "_be")) ;; Undo End ((eq "E" (strcase #BeginEnd)) (command "_.undo" "_e")) ) ;_ cond (setvar "cmdecho" #OldCmdecho) ) ;; VLA Undo Options ((eq "V" (strcase #CommandVLA)) (cond ;; Undo Begin ((eq "B" (strcase #BeginEnd)) (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-Acad-Object) ) ;_ vla-get-ActiveDocument ) ;_ vla-StartUndoMark ) ;; Undo End ((eq "E" (strcase #BeginEnd)) (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-Acad-Object) ) ;_ vla-get-ActiveDocument ) ;_ vla-EndUndoMark ) ) ;_ cond ) ) ;_ cond ) ;_ if ) ;_ defun ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN ROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (vl-load-com) (AT:Undo "V" "B") ;; background offset setting (setq #BackgroundOffset 1.2) (cond ;; select mtext and multileaders ((setq #SSList (AT:SS->List (ssget ":L" '((0 . "MTEXT,MULTILEADER"))) T) ) ;_ setq ;; something selected, time to process data (mapcar '(lambda (x) (cond ;; mtext ((eq (vla-get-ObjectName x) "AcDbMText") (if (eq (vla-get-backgroundfill x) :vlax-false) (progn ;; set backgroundfill to true (vla-put-backgroundfill x :vlax-true) ;; convert object to ename and entmod offset (setq #Ent (entget (vlax-vla-object->ename x))) (entmod (subst (cons 45 #BackgroundOffset) (assoc 45 #Ent) #Ent ) ;_ subst ) ;_ entmod ) ;_ progn ;; set backgroundfill to false (vla-put-backgroundfill x :vlax-false) ) ;_ if ) ;; multileader ((eq (vla-get-ObjectName x) "AcDbMLeader") (if (eq (vla-get-TextBackgroundFill x) :vlax-false) (progn ;; set background fill to true (vla-put-TextBackgroundFill x :vlax-true) ;; convert object to ename and entmod offset (setq #Ent (entget (vlax-vla-object->ename x))) (entmod (subst (cons 141 #BackgroundOffset) (assoc 141 #Ent) #Ent ) ;_ subst ) ;_ entmod ) ;_ progn ;; set backgroundfill to false (vla-put-TextBackgroundFill x :vlax-false) ) ;_ if ) ) ;_ cond ) ;_ lambda #SSList ) ;_ mapcar ) ) ;_ cond (AT:Undo "V" "E") (princ) ) ;_ defun
Solved! Go to Solution.
Solved by Lee_Mac. Go to Solution.
devitg,
Attached is a sample drawing with a couple of mleader objects in it. Looking into it more, one lead I can give is the code might be processing the mleader object under the mtext condition. I think this because the dotted pair of 45 gets modified in the mtext condition, and the 45 dotted pair in mleader controls the line spacing. In mtext, it controls the background mask border offset factor.
Also, I don't think the code is adjusting the mleader linespacing factor to match the TSPACEFAC variable, I think it's just adjusting it to 1.0.
Much thanks for looking at this.
Mike
I'm not sure I follow you. The LSP routine is a modifier of objects already in a drawing, so I don't know what sending me a revised drawing would do. The only difference I see between the two objects in the drawing you sent is one has the background mask turned on and one has it turned off.
I'm trying to figure out what is wrong with the LSP code.
MSJ9199, as I understood you , your problem is that when you apply the LISP , it change the line spacing .
What I show , is a way that the line spacing do not change when you toggle background mask turned on and off .
(defun bakgr-toggle (mleader-obj ) (if ( = (vla-get-TextBackgroundFill mleader-obj):vlax-true) (vla-put-TextBackgroundFill mleader-obj :vlax-false) (vla-put-TextBackgroundFill mleader-obj :vlax-true ) ) )
@devitg wrote:(defun bakgr-toggle (mleader-obj ) (if ( = (vla-get-TextBackgroundFill mleader-obj):vlax-true) (vla-put-TextBackgroundFill mleader-obj :vlax-false) (vla-put-TextBackgroundFill mleader-obj :vlax-true ) ) )
(defun bakgr-toggle ( obj ) (vlax-put obj 'textbackgroundfill (~ (vlax-get obj 'textbackgroundfill))) )
I Lee , as I understand this symbol ~ seem to be like a NOT operator . Can you, please, give us further information??
devitg wrote:I Lee , as I understand this symbol ~ seem to be like a NOT operator . Can you, please, give us further information?
Yes, the "~" symbol is a bitwise NOT function returning the 1's complement of the argument - that is, inverting all the bits of the argument.
Therefore, for an input argument of 0 (stored as a 32-bit signed integer):
0000 0000 0000 0000 0000 0000 0000 0000 = 0
We have an output of -1 (since 32-bit signed integers use a two's complement binary representation):
1111 1111 1111 1111 1111 1111 1111 1111 = -1
Similarly, applying the same operation to the binary representation of -1 will result in 0.
Now, since the :vlax-false & :vlax-true symbols may be represented using 0 and -1 respectively when using the undocumented vlax-get / vlax-put functions, we have a property toggle function.
Lee
You're welcome devitg
devitg & Lee_Mac,
Thank you for the very efficient code to toggle the background mask on and off. There is still one part of this lisp routine that I'm trying to figure out how it would work with Lee_Mac's code.
Besides toggling the mask on and off, this lisp also sets the mask to criteria defined in the lisp. I didn't make that clear in my first post. The background mask dialog box has two other options in it - setting the Border Offset factor (I prefer 1.2) and setting the Fill Color (I prefer it uses the drawing background color). I've attached a screenshot of it.
Like I also said in the beginning, I'm having trouble with the routine modifying the linespace factor for mleaders. It would be nice if I could get the lisp to stop doing that. Otherwise I'm no further than when I started.
Below is the relevant code that modifies/defines the background mask definition for mtext and mleaders. I removed a lot of the bloat that I previously posted.
Much thanks for all your help!
;; background offset setting (setq #BackgroundOffset 1.2) (cond ;; select mtext and multileaders ((setq #SSList (AT:SS->List (ssget ":L" '((0 . "MTEXT,MULTILEADER"))) T) ) ;_ setq ;; something selected, time to process data (mapcar '(lambda (x) (cond ;; mtext ((eq (vla-get-ObjectName x) "AcDbMText") (if (eq (vla-get-backgroundfill x) :vlax-false) (progn ;; set backgroundfill to true (vla-put-backgroundfill x :vlax-true) ;; convert object to ename and entmod offset (setq #Ent (entget (vlax-vla-object->ename x))) (entmod (subst (cons 45 #BackgroundOffset) (assoc 45 #Ent) #Ent ) ;_ subst ) ;_ entmod ) ;_ progn ;; set backgroundfill to false (vla-put-backgroundfill x :vlax-false) ) ;_ if ) ;; multileader ((eq (vla-get-ObjectName x) "AcDbMLeader") (if (eq (vla-get-TextBackgroundFill x) :vlax-false) (progn ;; set background fill to true (vla-put-TextBackgroundFill x :vlax-true) ;; convert object to ename and entmod offset (setq #Ent (entget (vlax-vla-object->ename x))) (entmod (subst (cons 141 #BackgroundOffset) (assoc 141 #Ent) #Ent ) ;_ subst ) ;_ entmod ) ;_ progn ;; set backgroundfill to false (vla-put-TextBackgroundFill x :vlax-false) ) ;_ if ) ) ;_ cond ) ;_ lambda #SSList ) ;_ mapcar ) ) ;_ cond
@mjs9199 wrote:Besides toggling the mask on and off, this lisp also sets the mask to criteria defined in the lisp. I didn't make that clear in my first post. The background mask dialog box has two other options in it - setting the Border Offset factor (I prefer 1.2) and setting the Fill Color (I prefer it uses the drawing background color).
Maybe my Background Mask program can help?
@mjs9199 wrote:
Wow Lee_Mac, that is pretty impressive. I am going to have to check out
your website too - looks like it has a lot of cool stuff!
Thanks Mike - feel free to browse my site at your leisure!
@mjs9199 wrote:
I don't think program will be as efficient for me as the lisp I
currently use. Since almost all of the objects I add a mask to will
have the same settings, the lisp is quicker to just set the mask with
those default settings. If I select objects with no mask, it turns on
background mask and sets the mask with the default settings. There is
no further input from me.I hope that makes sense. I'm not trying to toss out your solutions, but
they aren't fixing the real problem I have, which is just some weird
behavior with the current code.
I understand - that's not a problem at all.
Looking over the code you have, I see no reason why the program should alter the MLeader line spacing, and so I couldn't really offer a fix for the code. However, if my mask program changes the the background mask without altering the MLeader line spacing, this program could be quite easily modified to bypass the dialog and use default settings specified in the code.
(please don't interpret this as me trying to plug my program!)
Lee
@Lee_Mac wrote:
Looking over the code you have, I see no reason why the program should alter the MLeader line spacing, and so I couldn't really offer a fix for the code. However, if my mask program changes the the background mask without altering the MLeader line spacing, this program could be quite easily modified to bypass the dialog and use default settings specified in the code.
(please don't interpret this as me trying to plug my program!)
Lee
I would be very interested in the program if it can be setup like that! Is your program just a lisp file that I could modify or is it closed source (meaning you would have to modify)?
@mjs9199 wrote:
I would be very interested in the program if it can be setup like that!
Is your program just a lisp file that I could modify or is it closed source (meaning you would have to modify)?
Every program published on my site is open-source and comes with these terms (unless otherwise stated).
In short: you may modify the programs, providing that you do not distribute the modified version without prior permission.
I shall look to post a modified version of the program for you when I get some time.
Lee
Hi Lee_Mac
Now this is interesting. I finally got a chance to use your mask lsp file. Very nicely put together! What's interesting is that your file exhibits the same behavior. I don't think it's poor coding, I think there is a bug with mleaders. Either that or there is something with my setup that would cause both lsp routines to do the same thing.
At this point, I will learn to live with the issue. I'm going to flag this post as solved.
Mike
Thanks Mike, I'm glad you like the program!
I'm honestly puzzled as to what could be causing the line spacing issue, however since this result is received when using both the original posted code and my suggested program, this would suggest that the issue is local to something in your AutoCAD setup rather than a bug in both the programs, as you have noted in your post. With that said, I wouldn't know what setting is the culprit...
With the hectic workload following the new year, I unfortunately didn't get around to modifying my Background Mask program, but will keep this thread noted and if I eventually have some free time, I'll look to post the modified version as discussed.
Lee