I have this AutoLisp code and I want to ask 2 questins about it:
1. how can I make the polyline visible during drawing it(or while selecting the points)?
2. how can I change the color of the polyline but not the layer?
Many many thanks if i get an answer.
(defun c:nyomvodal (/ osmode clayer celtype)
;; save the current osmode, clayer and celtype
(setq osmode (getvar "osmode"))
(setq clayer (getvar "clayer"))
(setq celtype (getvar "celtype"))
;; create a new layer and make it current
(command "_layer" "_make" "nyomvodal" "_color" 3 "nyomvodal" "")
;; set the current osmode and line type
(setvar "osmode" 0)
(setvar "celtype" "16-os cso")
;; use vla-catch-all-apply to avoid exiting code if user cancels
(vl-catch-all-apply
'(lambda (/ pt lst)
;; get points form user
(while (setq pt (getpoint "\nPick point: "))
(setq lst (cons pt lst))
)
(if (< 2 (length lst))
(progn
;; create the polyline
(command "_pline")
(foreach p (reverse lst)
(command p)
)
(command "")
)
)
)
)
;; restore the previous system variables values
(setvar "osmode" osmode)
(setvar "clayer" clayer)
(setvar "celtype" celtype)
(princ)
)
The easiest would be just run command PLINE and wait until user will end.
Color You can change by system variable CECOLOR.
To restore defaults by system variables You can use error catching (in case when user click Esc ), when user ends with [enter] [space] You will restore defaults by call (*error*) function
(defun c:nyomvodal (/ osmode clayer celtype
*error* ) (defun *error* ( msg / )
(if (not (null msg ) ) (progn (princ "\nname:*error*: " ) (princ msg ) (princ "\n") ) )
(setvar "osmode" osmode)
(setvar "clayer" clayer)
(setvar "celtype" celtype)
(setvar 'CECOLOR cecolor)
)
;; save the current osmode, clayer and celtype
(setq osmode (getvar "osmode"))
(setq clayer (getvar "clayer"))
(setq celtype (getvar "celtype"))
(setq cecolor (getvar "CECOLOR"))
;; create a new layer and make it current
(command "_layer" "_make" "nyomvodal" "_color" 3 "nyomvodal" "")
;; set the current osmode and line type
(setvar "osmode" 0)
(setvar "CECOLOR" "1")
;(setvar "celtype" "16-os cso")
(command "_pline" pause)
(*error* nil) ; to restore default color, layer ...
(princ)
)
Related
I have to write the function that determines the number and values of block attributes in AutoLisp.
I have function which count the atributes:
(defun c:Test (/ s ss)
(if (and (princ "\n Select FIRST Attributed Block :")
(setq s (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1))))
(princ "\n Select the SECOND Attributed Block :")
(setq ss (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1))))
)
(mapcar
'length
(mapcar
'(lambda (a)
(mapcar
'(lambda (x) (vla-get-textstring x))
(vlax-invoke (vlax-ename->vla-object a) 'getattributes)
)
)
(list (ssname s 0) (ssname ss 0))
)
)
)
)**
A function that returns the values of attributes:
(defun c:Test (/ ss n e x)
(while (progn (princ "\n Select single attributed block :")
(setq ss (ssget "_+.:S" '((0 . "INSERT") (66 . 1))))
)
(setq n (entnext (ssname ss 0)))
(while (not (eq (cdr (assoc 0 (setq e (entget n)))) "SEQEND" ))
(if (eq (cdr (assoc 0 e)) "ATTRIB")
(print (cdr (assoc 1 e)))
)
(setq n (entnext n))
)
)
(princ)
)
Could you help me to combine this to functions into one?
Here is a lisp program that will loop over all blocks from a user selection set and:
1.) print block name
2.) print the association list of AttributeTag.AttributeValue
3.) print the list of AttributeTags
4.) print the list of AttributeValues
5.) print the number of AttributeValues
I also attached what the command line output should look like.
Lisp command line output
;;www.cadwiki.net
(defun c:test (/ SSINPUT)
(setq ssInput (ssget (list '(0 . "insert"))))
(PRINT-BLOCK-ATTRIBUTE-INFO ssInput)
(princ)
)
(defun PRINT-BLOCK-ATTRIBUTE-INFO (ssInput / ATTRIBUTETAGS ATTRIBUTETAGSTOVALUES ATTRIBUTEVALUES BLOCKENTITY BLOCKVLAOBJECT I NUMBEROFBLOCKATTRIBUTES
)
(setq i 0)
(if (= ssInput nil)
(progn
(princ "ssInput was nothing, exiting.")
(exit)
)
)
(princ (strcat "\nItems in selection set: " (itoa (sslength ssInput))))
(while (< i (sslength ssInput))
(setq blockEntity (ssname ssInput i))
(setq blockVlaObject (vlax-ename->vla-object blockEntity))
(setq attributeTagsToValues (GET-BLOCK-ATTRIBUTE-NAME-TO-VALUE-ASSOC blockEntity))
(princ (strcat "\nBlock name: " (vla-get-name blockVlaObject)))
(princ "\nBlock attributes tag to values association list: ")
(princ attributeTagsToValues)
(setq attributeTags (GET-NTHS-FROM-LISTS 0 attributeTagsToValues nil))
(princ "\nBlock attribute tags list: ")
(princ attributeTags)
(setq attributeValues (GET-LAST-ITEM-FROM-EACH-LIST attributeTagsToValues))
(princ "\nBlock attributes values list: ")
(princ attributeValues)
(princ "\nNumber of block attributes: ")
(setq numberOfBlockAttributes (itoa (length attributeValues)))
(princ numberOfBlockAttributes)
(setq i (+ i 1))
)
)
(defun GET-NTHS-FROM-LISTS (N LSTs removeDuplicates / CT LST2 LST IT)
(setq LST2 nil)
(foreach LST LSTs
(setq IT (nth N LST))
(if removeDuplicates
(if (not (member IT LST2))
(setq LST2 (append LST2 (list IT)))
)
(setq LST2 (append LST2 (list IT)))
)
)
LST2
)
(defun GET-LAST-ITEM-FROM-EACH-LIST (LSTs / CDRs FAIL LST)
(setq CDRs nil
FAIL nil
)
(if (not (= (type LSTs) 'LIST))
(setq FAIL "not a list")
)
(if (not FAIL)
(foreach LST LSTs
(setq FAIL (cond
((not (= (type LST) 'LIST)) "non-list member")
((not (cdr LST)) "no CDR")
(T nil)
)
)
(if (not FAIL)
(setq CDRs (append CDRs (list (cdr LST))))
)
)
)
CDRs
)
(defun GET-BLOCK-ATTRIBUTE-NAME-TO-VALUE-ASSOC (entity / COUNTER COUNTER2 COUNTERMAX COUNTERMAX2 DXFCODE0 DXFCODE2 DXFCODE66 DXFCODE8 DXFCODECODE-1 ENTITIESTORETURN ENTITYDXFCODES *ERROR* RETURNLIST
SUPPLIEDTRUENAME TRUENAME ATTRIBUTETAG ATTRIBUTEVALUE DXFCODE-1 ENTITYNAMEFORDRILLING SUBLIST TAGSANDVALUES THECALLINGFUNCTIONSNAME
)
(setq counter 0) ;initialize counter to 0 for while loop
(if ;if
(/= entity nil) ;entity is not nil
(progn ;progn wrap
(setq entityDxfCodes (entget entity)) ;set the varaible entityDxfCodes to the list of entities from the en varaible
;; you can use the method here to find any value from a dxfCodecode
(setq dxfCode-1 (cdr (assoc -1 entityDxfCodes))) ;set dxfCode-1 to the second element of the item that has -1 as it's first element, this is the entity name
(setq dxfCode0 (cdr (assoc 0 entityDxfCodes))) ;set dxfCode0 to the element of the item that has 0 as it's first element, this is the entity type
(setq dxfCode2 (cdr (assoc 2 entityDxfCodes))) ;set dxfCode8 to the second element of the item that has 8 as it's first element, this is the name, or block name
(setq dxfCode8 (cdr (assoc 8 entityDxfCodes))) ;set dxfCode8 to the second element of the item that has 8 as it's first element, this is the layer
(setq dxfCode66 (cdr (assoc 66 entityDxfCodes))) ;set dxfCode66 to the second element of the item that has 66 as it's first element, this is the attribute flag
(setq entityNameForDrilling entity)
(if ;if start
(= dxfCode66 1) ;entity attribute flag is 1
(progn ;progn wrap
(while (/= dxfCode0 "SEQEND") ;while loop to drill to each sub entity in a block
(setq attributeTag (cdr (assoc 2 entityDxfCodes))) ;set attributeTag to the second element of the second Dxf code (assoc 2) of the entityDxfCodes variable
(setq attributeValue (cdr (assoc 1 entityDxfCodes))) ;set attributeValue to the second element of the first Dxf code (assoc 1) of the entityDxfCodes variable
(if
(/= attributeValue nil)
(progn
(setq sublist (cons attributeTag attributeValue))
(setq tagsAndValues (cons sublist TagsAndValues))
)
)
(setq entityNameForDrilling (entnext entityNameForDrilling))
(setq entityDxfCodes (entget entityNameForDrilling))
(setq dxfCode0 (cdr (assoc 0 entityDxfCodes)))
)
) ;progn wrap end
) ;if end
) ;progn wrap end
) ;if end
(setq returnList tagsAndValues)
)
I would like to ask a question about automatizing polyline drawing. Here I have a FUNC and I want to add more specific commands. What I mean: I want the polyline to be assigned to a chosen layer automatically and i also want to set the line type to my custom line type. Thanks for the answers.
Here is my code:
You can get the newly created polyline with the entlast function and change its properties with _chprop command.
(defun c:nyomvodal (/ pt lst)
;; create a new layer
(command "_layer" "_new" "nyomvodal" "_color" 3 "nyomvodal" "")
;; get points form user
(while (setq pt (getpoint "\nPick point: "))
(setq lst (cons pt lst))
)
(if (< 2 (length lst))
(progn
;; create the polyline
(command "_pline")
(foreach p (reverse lst)
(command "_non" p)
)
(command "")
(command "_chprop" (entlast) "" "_layer" "nyomvodal" "_ltype" "axes" "")
)
)
(princ)
)
But, typically, we save current values of the OSMODE, CLAYER and CELTYPE system variables, set new values, draw the polyline, and restore the previous values.
(defun c:nyomvodal (/ osmode clayer celtype)
;; save the current osmode, clayer and celtype
(setq osmode (getvar "osmode"))
(setq clayer (getvar "clayer"))
(setq celtype (getvar "celtype"))
;; create a new layer and make it current
(command "_layer" "_make" "nyomvodal" "_color" 3 "nyomvodal" "")
;; set the current osmode and line type
(setvar "osmode" 0)
(setvar "celtype" "AXES")
;; use vla-catch-all-apply to avoid exiting code if user cancels
(vl-catch-all-apply
'(lambda (/ pt lst)
;; get points form user
(while (setq pt (getpoint "\nPick point: "))
(setq lst (cons pt lst))
)
(if (< 2 (length lst))
(progn
;; create the polyline
(command "_pline")
(foreach p (reverse lst)
(command p)
)
(command "")
)
)
)
)
;; restore the previous system variables values
(setvar "osmode" osmode)
(setvar "clayer" clayer)
(setvar "celtype" celtype)
(princ)
)
I'm trying to insert blocks with custom properties. How do I set those variables?
Within the Deciduous block there is a custom property called "visibility" with various different styles (Visibility 1, Visibility 2, Visibility 3, ...).
For instance, how would I insert the Deciduous block with Visibility 3.
(DEFUN C:TREE ( / DECIDUOUS CONIFER SHRUBMEDIUM SHRUBSMALL)
(INITGET 1 "DECIDUOUS CONIFER SHRUBMEDIUM SHRUBSMALL")
(OR
(SETQ RETKWORD (GETKWORD "\nSpecify tree type: [DECIDUOUS/CONIFER/SHRUBMEDIUM/SHRUBSMALL]:"))
(SETQ RETKWORD "DECIDUOUS")
)
(IF (= RETKWORD "DECIDUOUS")
(PROGN
(SETQ OLDLAYER (GETVAR "CLAYER"))
(SETQ FLAG (TBLSEARCH "LAYER" "L-PLNT-DECD"))
(IF FLAG
(SETVAR "CLAYER" "L-PLNT-DECD")
)
(INITGET 1 "Visibility1 Visibility2 Visibility3")
(OR
(SETQ CMDKWORD (GETKWORD "\nPick a command: [Visibility1/Visibility2/Visibility3]:"))
)
(IF (= CMDKWORD "Visibility3")
(PROGN
(COMMAND "INSERT"
"TT-L-TREE-DECIDUOUS"
)
)
)
(PRINC)
)
)
)
The answer to this question ultimately depends on whether or not you require the visual preview of the inserted block reference, as afforded by the AutoCAD INSERT command.
Since the standard AutoCAD INSERT command does not prompt for dynamic block parameter values during block insertion, you'll need to insert the block and then manipulate the visibility state using the ActiveX properties & methods of the inserted dynamic block reference, specifically, using the getdynamicblockproperties method.
If the visual preview of the inserted block is NOT required...
...then you can forego the INSERT command entirely, and use the insertblock method of the target container object (modelspace/paperspace/block definition), which will return a block reference vla-object.
Here is a basic example demonstrating how to use the insertblock method:
(defun c:test ( / dwg ins )
(if
(and
(setq dwg (getfiled "Select Block" "" "dwg" 16))
(setq ins (getpoint "\nSpecify insertion point: "))
)
(vla-insertblock
(vlax-get-property
(vla-get-activedocument (vlax-get-acad-object))
(if (= 1 (getvar 'cvport))
'paperspace
'modelspace
)
)
(vlax-3D-point (trans ins 1 0))
dwg
1.0 1.0 1.0 0.0
)
)
(princ)
)
(vl-load-com) (princ)
This method will return a block reference vla-object, whose dynamic block properties you can then manipulate using the array of dynamic block properties returned by the getdynamicblockproperties method.
Since you are looking to modify the Visibility State in particular, you may wish to consider the following set of functions that I have developed as part of my dynamic block library to modify the visibility state of a supplied block reference object:
;; Set Dynamic Block Visibility State - Lee Mac
;; Sets the Visibility Parameter of a Dynamic Block (if present) to a specific value (if allowed)
;; blk - [vla] VLA Dynamic Block Reference object
;; val - [str] Visibility State Parameter value
;; Returns: [str] New value of Visibility Parameter, else nil
(defun LM:SetVisibilityState ( blk val / vis )
(if
(and
(setq vis (LM:getvisibilityparametername blk))
(member (strcase val) (mapcar 'strcase (LM:getdynpropallowedvalues blk vis)))
)
(LM:setdynpropvalue blk vis val)
)
)
;; Get Visibility Parameter Name - Lee Mac
;; Returns the name of the Visibility Parameter of a Dynamic Block (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; Returns: [str] Name of Visibility Parameter, else nil
(defun LM:getvisibilityparametername ( blk / vis )
(if
(and
(vlax-property-available-p blk 'effectivename)
(setq blk
(vla-item
(vla-get-blocks (vla-get-document blk))
(vla-get-effectivename blk)
)
)
(= :vlax-true (vla-get-isdynamicblock blk))
(= :vlax-true (vla-get-hasextensiondictionary blk))
(setq vis
(vl-some
'(lambda ( pair )
(if
(and
(= 360 (car pair))
(= "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr pair)))))
)
(cdr pair)
)
)
(dictsearch
(vlax-vla-object->ename (vla-getextensiondictionary blk))
"ACAD_ENHANCEDBLOCK"
)
)
)
)
(cdr (assoc 301 (entget vis)))
)
)
;; Get Dynamic Block Property Allowed Values - Lee Mac
;; Returns the allowed values for a specific Dynamic Block property.
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; Returns: [lst] List of allowed values for property, else nil if no restrictions
(defun LM:getdynpropallowedvalues ( blk prp )
(setq prp (strcase prp))
(vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'allowedvalues)))
(vlax-invoke blk 'getdynamicblockproperties)
)
)
;; Set Dynamic Block Property Value - Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil
(defun LM:setdynpropvalue ( blk prp val )
(setq prp (strcase prp))
(vl-some
'(lambda ( x )
(if (= prp (strcase (vla-get-propertyname x)))
(progn
(vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
(cond (val) (t))
)
)
)
(vlax-invoke blk 'getdynamicblockproperties)
)
)
You might call the above functions from the earlier example I provided in the following way (changing the name of the visibility state to suit your block of course):
(defun c:test ( / dwg ins )
(if
(and
(setq dwg (getfiled "Select Block" "" "dwg" 16))
(setq ins (getpoint "\nSpecify insertion point: "))
)
(LM:SetVisibilityState
(vla-insertblock
(vlax-get-property
(vla-get-activedocument (vlax-get-acad-object))
(if (= 1 (getvar 'cvport))
'paperspace
'modelspace
)
)
(vlax-3D-point (trans ins 1 0))
dwg
1.0 1.0 1.0 0.0
)
"YourVisibilityState"
)
)
(princ)
)
(vl-load-com) (princ)
If the visual preview of the inserted block IS required...
...Then aside from rolling your own version of the standard INSERT command using a grread loop (which would also need to imitate all drawing aids, such as Object Snap, and Orthomode), you would need to make use of the INSERT command.
However, since the visibility state of the block can only be changed following the insertion of the block reference, the visual preview displayed to the user will be inaccurate.
To get the best of both worlds, I have previously proposed the following possible solution (along with an accompanying function posted here):
;; Example demonstrating a method to insert a Dynamic Block with a Visibility State already set.
;; Lee Mac - 2013-12-24
(defun c:test ( / *error* att blk def doc ent new obj par spc tmp vis )
(defun *error* ( msg )
(if (= 'int (type att))
(setvar 'attreq att)
)
(foreach obj (list new def)
(if (and (= 'vla-object (type obj)) (not (vlax-erased-p obj)))
(vl-catch-all-apply 'vla-delete (list obj))
)
)
(if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
(cond
( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer))))))
(princ "\nCurrent layer locked.")
)
( (null (setq blk (getfiled "Select Dynamic Block with Visibility States" "" "dwg" 16)))
(princ "\n*Cancel*")
)
( (progn
(setq doc (vla-get-activedocument (vlax-get-acad-object))
spc (vlax-get-property doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
obj (vlax-invoke spc 'insertblock '(0.0 0.0 0.0) blk 1.0 1.0 1.0 0.0)
)
(vla-put-visible obj :vlax-false)
(= :vlax-false (vla-get-isdynamicblock obj))
)
(princ "\nSelected block is not dynamic.")
(vla-delete obj)
)
( (null (setq par (LM:getvisibilityparametername obj)))
(princ "\nSelected block does not have a visibility parameter.")
(vla-delete obj)
)
( (null (setq vis (car (LM:listbox "Choose a Visibility State" (acad_strlsort (LM:getdynpropallowedvalues obj par)) 0))))
(princ "\n*Cancel*")
(vla-delete obj)
)
( t
(LM:setdynpropvalue obj par vis)
(setq tmp 0)
(while (tblsearch "block" (setq blk (strcat "tmp" (itoa (setq tmp (1+ tmp)))))))
(vla-put-visible
(car
(vlax-invoke doc
'copyobjects
(list obj)
(setq def (vlax-invoke (vla-get-blocks doc) 'add '(0.0 0.0 0.0) blk))
)
)
:vlax-true
)
(vla-delete obj)
(setq ent (entlast)
att (getvar 'attreq)
)
(setvar 'attreq 0)
(if
(and
(vl-cmdf "_.-insert" blk "_S" 1.0 "_R" 0.0 "\\")
(not (eq ent (setq ent (entlast))))
(= "AcDbBlockReference" (vla-get-objectname (setq new (vlax-ename->vla-object ent))))
)
(progn
(vla-explode new)
(vla-delete new)
)
)
(vl-catch-all-apply 'vla-delete (list def))
)
)
(princ)
)
;; Get Visibility Parameter Name - Lee Mac
;; Returns the name of the Visibility Parameter of a Dynamic Block (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; Returns: [str] Name of Visibility Parameter, else nil
(defun LM:getvisibilityparametername ( blk / vis )
(if
(and
(vlax-property-available-p blk 'effectivename)
(setq blk
(vla-item
(vla-get-blocks (vla-get-document blk))
(vla-get-effectivename blk)
)
)
(= :vlax-true (vla-get-isdynamicblock blk))
(= :vlax-true (vla-get-hasextensiondictionary blk))
(setq vis
(vl-some
'(lambda ( pair )
(if
(and
(= 360 (car pair))
(= "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr pair)))))
)
(cdr pair)
)
)
(dictsearch
(vlax-vla-object->ename (vla-getextensiondictionary blk))
"acad_enhancedblock"
)
)
)
)
(cdr (assoc 301 (entget vis)))
)
)
;; Get Dynamic Block Property Allowed Values - Lee Mac
;; Returns the allowed values for a specific Dynamic Block property.
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; Returns: [lst] List of allowed values for property, else nil if no restrictions
(defun LM:getdynpropallowedvalues ( blk prp )
(setq prp (strcase prp))
(vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'allowedvalues)))
(vlax-invoke blk 'getdynamicblockproperties)
)
)
;; Set Dynamic Block Property Value - Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil
(defun LM:setdynpropvalue ( blk prp val )
(setq prp (strcase prp))
(vl-some
'(lambda ( x )
(if (= prp (strcase (vla-get-propertyname x)))
(progn
(vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
(cond (val) (t))
)
)
)
(vlax-invoke blk 'getdynamicblockproperties)
)
)
;; List Box - Lee Mac
;; Displays a DCL list box allowing the user to make a selection from the supplied data.
;; msg - [str] Dialog label
;; lst - [lst] List of strings to display
;; bit - [int] 1=allow multiple; 2=return indexes
;; Returns: [lst] List of selected items/indexes, else nil
(defun LM:listbox ( msg lst bit / dch des tmp rtn )
(cond
( (not
(and
(setq tmp (vl-filename-mktemp nil nil ".dcl"))
(setq des (open tmp "w"))
(write-line
(strcat "listbox:dialog{label=\"" msg "\";spacer;:list_box{key=\"list\";multiple_select="
(if (= 1 (logand 1 bit)) "true" "false") ";width=50;height=15;}spacer;ok_cancel;}"
)
des
)
(not (close des))
(< 0 (setq dch (load_dialog tmp)))
(new_dialog "listbox" dch)
)
)
(prompt "\nError Loading List Box Dialog.")
)
( t
(start_list "list")
(foreach itm lst (add_list itm))
(end_list)
(setq rtn (set_tile "list" "0"))
(action_tile "list" "(setq rtn $value)")
(setq rtn
(if (= 1 (start_dialog))
(if (= 2 (logand 2 bit))
(read (strcat "(" rtn ")"))
(mapcar '(lambda ( x ) (nth x lst)) (read (strcat "(" rtn ")")))
)
)
)
)
)
(if (< 0 dch)
(unload_dialog dch)
)
(if (and tmp (setq tmp (findfile tmp)))
(vl-file-delete tmp)
)
rtn
)
(vl-load-com) (princ)
My solution essentially involves temporarily inserting a block reference, configuring the visibility state appropriately, creating a temporary block definition containing the configured dynamic block, and then exploiting the visual preview offered by the standard INSERT command to insert the temporary block reference, which is then exploded & purged from the drawing.
Blocks with custom properties are called Dynamic blocks.
Details and samples You can find here
p.s.
Thank You #LeeMac
How can I toggle the case of letters (switch uppercase letters to lowercase and lowercase letters to uppercase) of a region's text in Emacs?
There are listed commands for conversion but nothing for toggling.
Example:
PLease toggLE MY LETTER case
should become:
plEASE TOGGle my letter CASE
You can do it with a regexp substitution:
M-x replace-regexp RET
\([[:upper:]]+\)?\([[:lower:]]+\)? RET
\,(concat (downcase (or \1 "")) (upcase (or \2 ""))) RET
It's up to you to bind a key to this.
I wrote it for you; it did not have thorough testing, but it appears to do what you seek.
The logic behind it is to loop over every single character in the text. If the character is equal to the character in downcase, append it to the return string in upcase. If not, append it in downcase. At the end, delete region and insert the return string.
It works immediate on a page of text, though I'd be wary to use it on huge texts (should be fine still).
(defun toggle-case ()
(interactive)
(when (region-active-p)
(let ((i 0)
(return-string "")
(input (buffer-substring-no-properties (region-beginning) (region-end))))
(while (< i (- (region-end) (region-beginning)))
(let ((current-char (substring input i (+ i 1))))
(if (string= (substring input i (+ i 1)) (downcase (substring input i (+ i 1))))
(setq return-string
(concat return-string (upcase (substring input i (+ i 1)))))
(setq return-string
(concat return-string (downcase (substring input i (+ i 1)))))))
(setq i (+ i 1)))
(delete-region (region-beginning) (region-end))
(insert return-string))))
Commands upcase-region, downcase-region, andcapitalize-region are not toggles, and are perhaps the "conversion" commands you referred to. Here is a command that cycles among them.
(defvar cycle-region-capitalization-last 'upper)
(defun cycle-region-capitalization (&optional msgp)
"Cycle the region text among uppercase, lowercase and capitalized (title case)."
(interactive "p")
(setq cycle-region-capitalization-last
(case cycle-region-capitalization-last
(upper (call-interactively #'downcase-region) 'lower)
(lower (call-interactively #'capitalize-region) 'title)
(title (call-interactively #'upcase-region) 'upper)))
(when msgp (message "Region is now %scase" cycle-region-capitalization-last)))
If you mean letter case, then this function works nicely: http://ergoemacs.org/emacs/modernization_upcase-word.html
(defun toggle-letter-case ()
"Toggle the letter case of current word or text selection.
Toggles between: “all lower”, “Init Caps”, “ALL CAPS”."
(interactive)
(let (p1 p2 (deactivate-mark nil) (case-fold-search nil))
(if (region-active-p)
(setq p1 (region-beginning) p2 (region-end))
(let ((bds (bounds-of-thing-at-point 'word) ) )
(setq p1 (car bds) p2 (cdr bds)) ) )
(when (not (eq last-command this-command))
(save-excursion
(goto-char p1)
(cond
((looking-at "[[:lower:]][[:lower:]]") (put this-command 'state "all lower"))
((looking-at "[[:upper:]][[:upper:]]") (put this-command 'state "all caps") )
((looking-at "[[:upper:]][[:lower:]]") (put this-command 'state "init caps") )
((looking-at "[[:lower:]]") (put this-command 'state "all lower"))
((looking-at "[[:upper:]]") (put this-command 'state "all caps") )
(t (put this-command 'state "all lower") ) ) ) )
(cond
((string= "all lower" (get this-command 'state))
(upcase-initials-region p1 p2) (put this-command 'state "init caps"))
((string= "init caps" (get this-command 'state))
(upcase-region p1 p2) (put this-command 'state "all caps"))
((string= "all caps" (get this-command 'state))
(downcase-region p1 p2) (put this-command 'state "all lower")) )
) )
I liked the other answer's technique of comparing this-command and last-command,
so I've incorporated it into my old function. Here's the result:
(defun upcase-word-toggle ()
(interactive)
(let ((bounds (bounds-of-thing-at-point 'symbol))
beg end
regionp)
(if (eq this-command last-command)
(setq regionp (get this-command 'regionp))
(put this-command 'regionp nil))
(cond
((or (region-active-p) regionp)
(setq beg (region-beginning)
end (region-end))
(put this-command 'regionp t))
(bounds
(setq beg (car bounds)
end (cdr bounds)))
(t
(setq beg (point)
end (1+ beg))))
(save-excursion
(goto-char (1- beg))
(and (re-search-forward "[A-Za-z]" end t)
(funcall (if (char-upcasep (char-after))
'downcase-region
'upcase-region)
beg end)))))
(defun char-upcasep (letter)
(eq letter (upcase letter)))
(global-set-key (kbd "C->") 'upcase-word-toggle)
I am currently attempting to run a polyline between two blocks (first_block, second_block) that runs along another polyline, at the end of the action an insert function is called that populates an annotation block (cable_name_tag) with the details of the start and end block.
This polyline will transect other blocks and often needs to run in paralell with an underlying polyline (cable_ducting) so the user will need to option to select an appropriate part of the polyline to drop the annotation, as space is sometimes limited.
I have noted that if I comment out the second_block and provide a harcoded value the ssget function works without issue, so I am reasonably sure the issue is with either the syntax or the handling of the first_block and second_block in that code.
(defun c:cable ()
(vl-load-com)
(setvar "clayer" "cable layer")
(setvar "celtype" "bylayer")
(setvar "osmode" 515)
(command "_.pline"
(getpoint))
(while (> (getvar ' cmdactive) 0)
(command pause)
(princ "\npress enter to finish:"))
(setq elst
(entsel "\nselect cable segment: "))
(setq ename
(car elst))
(setq pt
(cadr elst))
(setq annopt pt)
(setq pt
(vlax-curve-getclosestpointto ename pt))
(setq param
(vlax-curve-getparamatpoint ename pt))
(setq preparam
(fix param))
(setq postparam
(1+ preparam))
(list (setq pt1
(vlax-curve-getpointatparam ename preparam))
(setq pt2
(vlax-curve-getpointatparam ename postparam)))
(setq cable
(entlast))
(setq cable_start
(vlax-curve-getstartparam cable))
(setq cable_start_point
(vlax-curve-getstartpoint cable))
(setq cable_end_point
(vlax-curve-getendpoint cable))
(setq cable_end
(angtos (angle '(0 0)
(vlax-curve-getfirstderiv cable 0.0))))
(setq first_block
(ssget "_c" cable_start_point cable_end_point
(list (cons 0 "insert")
(cons 2 "first_block"))))
(setq second_block
(ssget "_c" cable_start_point cable_end_point
(list (cons 0 "insert")
(cons 2 "second_block"))))
(setq end_cable
(ssname second_block 0))
(setq start_cable
(ssname first_block 0))
(setq $end_cable
(vla-get-textstring
(cadr (vlax-safearray->list
(variant-value
(vla-getattributes
(vlax-ename->vla-object end_cable)))))))
(setq $start_cable
(vla-get-textstring
(cadr (vlax-safearray->list
(variant-value
(vla-getattributes
(vlax-ename->vla-object start_cable)))))))
(setq cable_name
(vlax-curve-getendparam cable))
(command ; insert cable param
"-insert"
"cable_name_tag"
annopt
"1"
"1"
cable_angle
cable_name
$start_cable
$end_cable
"144"
cable_length))
I am stuck in a corner on this one, and would appreciate any help, advice or pointers anyone can offer.
Thank you all for your time.
Why not just use (entlast) to get the entity that was just created?