KozMos AnnoQuarX

  A powerful Visual LISP API to manipulate AutoCAD annotation objects

 

AnnoQuarX: Introduction
        AutoCAD supports many annotation types: TEXT, MTEXT, RTEXT, ARCALIGNEDTEXT, ATTRIBUTE (in/out block), LEADER, DIMENSION, FIELD and AcDbTable etc. AnnoQuarX is designed to manipulate all these annotation types as simple as simple text. The first generation of AnnoQuarX is focus on the annotation contents. Some very useful functions were developed to enable the user interactive operation for obtaining the indicated (pick object directly or pick AcDbTable cell region) annotations.

        AutoCAD use FIELD to realize some automatic link-and-update between various AutoCAD objects. In order to get access with the field codes, AnnoQuarX will individually proceed with them and return the paired list to store or display both content and field code, if an attribute is exist, the attribute tag will also be recorded.

AnnoQuarX: Publishing Functions


AQX:ANNOTATIVE-P
(AQX:ANNOTATIVE-P ObjectOrStyleName)
Test if an entity or TextStyle/DimStyle is annotative.

(AQX:ANNOTATIVE-P Obj)
 T
(AQX:ANNOTATIVE-P "DIMS")
 NIL

Argument 1 ENAME/STR The annotation object or TextStyle/DimStyle name
NIL for current TextStyle
Return SUCCESS T
FAILURE NIL
AQX:FIELDCODE
(AQX:FIELDCODE Object)
Get the field code string. If no field code, return "*None*".

(AQX:FIELDCODE Obj)
 "23%<\\AcObjProp Object(%<\\_ObjIdx 2130339688>%).Layer>%saf"

Argument 1 ENAME The annotation object.
Return SUCCESS The field code string.
FAILURE "*None*"
AQX:GETATTRIBUTES
(AQX:GETATTRIBUTES BlockObject/BlockName)
Get the attribute list from given block object or block name (search from block definition).
If the block contain no attributes, return NIL.

(AQX:GETATTRIBUTES Obj)
(<Entity name: 2250210> <Entity name: 2250250>... <Entity name: 22502d0>)

(AQX:GETATTRIBUTES "$DIMHH")
(<Entity name: 38506e0><Entity name: 3850910> ...<Entity name: 38506d0>) 

Argument 1 ENAME The parent block object or block name string.
Return SUCCESS The list contain all nested attribute object(s).
FAILURE "*None*"
AQX:GETCELLID
(AQX:GETCELLID CellContentObject)
Get the AcDbTable row and column ID from the cell content objects (mtext or attribute in AcBlockCell).

(AQX:GETCELLID obj)
(<Entity name: 7efa6738> 2 4)        Row = 2 and Column = 4

Argument 1 ENAME Thecell content MTEXT or nest object (mostly attribute) of block in cell.
Return SUCCESS The list contain AcDbTable object, row and column ID
FAILURE "*None*"
AQX:GETCELLID-MERGED
(AQX:GETCELLID-MERGED AcDbTable RowID ColumnID)
Get the row and column ID integers of a merged AcDbTable cell by indicating any cell ID within the merged cell.

(AQX:GETCELLID-MERGED obj 6 3)           "C5:E9"

Argument 1 ENAME The AcDbTable object.
Argument 2 ENAME The Row ID integer, NIL for 0.
Argument 3 ENAME The ColumnID integer, NIL for 0.
Return SUCCESS A four items list contain cell ID intergers:
(  LeftUpperCellRowID[INT]         LeftUpperCellColumnID[INT]
   RightLowerCellRowID[INT]       RightLowerCellColumnID[INT]
)
FAILURE "*None*"
AQX:GETCONTENT
(AQX:GETCONTENT Object)
Get the content data from annotation or parent object (Block or Dimension). Basically, the content data is a 3-item list of AttributeTagString, ContentString and FieldCodeString. If any of AttributeTagString, ContentString or FieldCodeString is empty, use "*None*" (case sensitive).
If the given object is MLeader with multiple-attribute block or multiple-attribute block itself, the return value will be list contains all attributes' content data, like ((Tag1 Content1 Field1)(Tag2 Content2 Field2)...)
If the given object is MLeader with non-attribute block, the function will return ("*None*" "*None*" "*None*")

(AQX:GETCONTENT Obj) DIMENSION Text
("*None*" "\A186" "*None*")

(AQX:GETCONTENT Obj) RTEXT
("*None*" "6wqe\\Pasdfasf\\Pasfasfsaf" "*None*")

(AQX:GETCONTENT Obj) ATTRIB without Field
("A" "6" "*None*")

(AQX:GETCONTENT Obj)
ATTRIB with Field
("A" "asfd\\Pas" "%<\\AcObjProp Object(%<\\_ObjIdx 2126878224>%).TextString>%")

(AQX:GETCONTENT Obj) TEXT/MTEXT/LEADER
("*None*" "asfd\\Pas" "*None*")

(AQX:GETCONTENT Obj) TEXT/MTEXT/LEADER with Field
("*None*" "zuxDIMdasfd" "zux%<\\AcObjProp Object(%<\\_ObjIdx 2126715224>%).TextStyle>%dasfd")

(AQX:GETCONTENT Obj)
 MLEADER content
("*None*" "cvasdfv\\Pasdf" "*None*")

(AQX:GETCONTENT Obj)
 MLEADER content with Field
 ("*None*" "cv$DIMHHasdfv\\Pasdf" "cv%<\\AcObjProp Object(%<\\_ObjIdx 2130350832>%).Name>%asdfv\\Pasdf")

(AQX:GETCONTENT Obj)
MLEADER block without ATTRIB
("*None*" "*None*" "*None*")

(AQX:GETCONTENT Obj)
MLEADER block with ATTRIB or BLOCK
(("DIMH" "0.000" "*None*")("NAME" "rdqr" "*None*"))

Argument 1 ENAME The annotation or block object.
Return SUCCESS The list of TagString, ContentString and FieldcodeString.
If any of TagString or FieldcodeString is empty, use "*None*".
FAILURE "*None*"
AQX:GETCONTENT-CELL
(AQX:GETCONTENT-CELL TableObject RowID ColumnID)
Get the content data of AcDbTable cell.

(AQX:GETCONTENT-CELL Obj 1 1)     MTEXT content
("wwds" "*None*")

(AQX:GETCONTENT-CELL Obj 1 1)
   MTEXT content with Field
("asAcDbCirclead" "as%<\\AcObjProp Object(%<\\_ObjIdx 2130339968>%).ObjectName>%ad")

(AQX:GETCONTENT-CELL Obj 1 1)
   Block content
("*None*" "*None*")

(AQX:GETCONTENT-CELL Obj 1 1)
   Block content with ATTRIB
(("DIMH" . "0.000") ("NAME" . "ROOM"))

Argument 1 ENAME The AcDbTable object.
Argument 2 ENAME The Row ID integer, NIL for 0.
Argument 3 ENAME The ColumnID integer, NIL for 0.
Return SUCCESS The return value varies by different cell types:
AcTextCell: Two items list (ContentString[STR] FieldCodeString[STR])
AcBlockCell (Block without attributes): Constant value of ("*None*" "*None*")
AcBlockCell (Block with attributes): List contain attributes' data ((Tag1 . Content1)(Tag2 . Content2)...)
Because Field is now not supported in attributes in AcBlockCell, So Field is not exist in return value.
If any of ContentString or FieldcodeString is empty, use "*None*".
FAILURE "*None*"
AQX:GETPARENT
(AQX:GETPARENT Object)
Get the parent Block, AcDbTable or Dimension object of given nested object.

(AQX:GETPARENT Obj)
 <Entity name: 7efa6738>

Argument 1 ENAME The nested object (in Block, AcDbTable or Dimension).
Return SUCCESS The parent (Block, AcDbTable or Dimension) object.
FAILURE "*None*"
AQX:MODIFYSTRING
(AQX:MODIFYSTRING SourceString ModifyMode ModifyData)
Modify a string based on 14 preset modes.

Only substitute 1st match
(AQX:MODIFYSTRING "abcdabcd" "SUBST1" '("a" "X" "c" "M"))
"XbMdabcd"

Substitute all matched
(AQX:MODIFYSTRING "abcdabcd" "SUBST" '("a" "X"))
"XbcdXbcd"

Substitute the 2nd and 3rd matched
(AQX:MODIFYSTRING "asdfasfhasdfasfgassfvasg" "substn" '("2 3" "a" "XX"))
"asdfasfhXXsdfXXsfgassfvasg"

Calculate the 2nd and 3rd number with "0.000" precision
(AQX:MODIFYSTRING "d21.423asf4.21de4s" "math" '(0 2 nil 3 "2 3"))
"d21.423asf8.420dee8.000s"

Calculate the 2nd and 3rd number with same precision
(AQX:MODIFYSTRING "d21.423asf4.21de4s" "math" '(0 2 nil nil "2 3"))
"d21.423asf8.42dee8s"

Argument 1 ENAME The source string
Argument 2 ENAME The modify mode, be one of the following:
  • 1STCAP:
    1st letter capitalized.
  • CLEAR:
    Clear content.
  • LOWER:
    All to lower letter.
  • MATH:
    Run calculation of the certain digit parts.
  • PREFIX:
    Add prefix.
  • PRESUFFIX:
    Add prefix and suffix together.
  • REPLACE, REPLACE1:
    Fully substitution with case sensitive (whole word match).
  • REPLACE0:
    Fully substitution without case sensitive (whole word match).
  • SUBST:
    Substitute all matched parts.
  • SUBST1:
    Substitute 1st matched part only.
  • SUBSTN:
    Substitute certain matched parts by order numbers.
  • SUFFIX:
    Add suffix.
  • UNIQUE:
    Overwrite with new content.
  • UPPER:
    All to upper letter.
Argument 3 ENAME The modify data
  • 1STCAP:
    Ignored.
  • CLEAR:
    Ignored.
  • LOWER:
    Ignored.
  • MATH:
    List contain parameters (A/B/C) of function y=a*x^2+b*x+c and the substitution ID string.
    If multiple substitution ID is used, use spacebar to separate the ID number in substitution ID string. The 1st match ID is 0. If match all. use "*".
  • PREFIX:
    The prefix string.
  • PRESUFFIX:
    List contain the prefix / suffix strings.
  • REPLACE, REPLACE1:
    List contain the new / old strings. As it is fully match, only 1 couple of new /old strings will be exist.
  • REPLACE0:
    List contain the new / old strings. As it is fully match, only 1 couple of new /old strings will be exist.
  • SUBST:
    List contain the new / old string pair(s).
    If multiple substitution is invoked, add all new and old strings into a flat list, just keep them in correct order: old 1st, then new.
  • SUBST1:
    List contain the new / old string pair(s).
    If multiple substitution is invoked, add all new and old strings into a flat list, just keep them in correct order: old 1st, then new.
  • SUBSTN:
    List contain the substitution ID string and  new / old string pair(s).
    If multiple substitution IDs are used, use spacebar to separate them. The 1st match ID is 0. "2" or "2 3 5" can be good example.
    If multiple substitution is invoked, add all new and old strings into a flat list, just keep them in correct order: old 1st, then new.
  • SUFFIX:
    The suffix string.
  • UNIQUE:
    The new unique string.
  • UPPER:
    Ignored.
Return SUCCESS The changed string.
FAILURE The source string without change.
AQX:MODIFYSTRINGDLG
(AQX:MODIFYSTRINGDLG)
Dialog version of parameters settings for AQX:MODIFYSTRING.


(AQX:MODIFYSTRINGDLG)
("PREFIX" "abc")

(AQX:MODIFYSTRINGDLG)
("SUBST1" ("123" "abc" "456" "xyz"))

(AQX:MODIFYSTRINGDLG)
("1STCAP" nil)

Return SUCCESS The parameters list needed by AQX:MODIFYSTRING. The return value is a two elements list, the 1st element is the modification mode such as "LOWER", or "PREFIX" etc. the second one varies. Different mode may return different data:
  • LOWER, UPPER, 1STCAP,
    The second item is NIL
  • PREFIX, SUFFIX, CLEAR, UNIQUE
    The second item is STRING
  • SUBST, SUBST1, REPLACE0, REPLACE1
    The second item is a string list contain the subtitution data, same syntax as AQX:MODIFYSTRING
  • PRESUFFIX
    The second item is a two strings list contain both the prefix and suffix.
FAILURE NIL
AQX:PICK-ANNO
(AQX:PICK-ANNO GivenPoint)
Get data of a picked annotation from given point.
If the given point is not available, prompt users to pick one.
 

(AQX:PICK-ANNO NIL)            Pick TEXT without Field
((<Entity name: 7efa6730> <Entity name: 7efa6730>)("*None*" "asfdasf" "*None*") (3345.45 514.688 0.0))

(AQX:PICK-ANNO NIL)            Pick TEXT without Field
((<Entity name: 7efa6730> <Entity name: 7efa6730>)
("*None*" "asWALLfdasf" "as%<\\AcVar.17.0 Lisp.#stair#>%fdasf")(3345.45 514.688 0.0))

(AQX:PICK-ANNO NIL)            Pick ATTDEF
((<Entity name: 7efa6738> <Entity name: 7efa6738>) ("SDFS" "dADadf" "*None*") (3510.03 -986.901 0.0))

(AQX:PICK-ANNO NIL)            Pick ATTRIB without Field
((<Entity name: 7efa6770> <Entity name: 7efa6768>) ("DIMH" "11.000" "*None*") (514.699 273.557 0.0))

(AQX:PICK-ANNO NIL)            Pick ATTRIB with Field
((<Entity name: 7efa6770> <Entity name: 7efa6768>)
("DIMH" "11.0SDFS00" "11.0%<\\AcObjProp Object(%<\\_ObjIdx 2130339640>%).TagString>%00")(514.699 273.557 0.0))

(AQX:PICK-ANNO NIL)            Pick MTEXT without Field
((<Entity name: 7efa67a0> <Entity name: 7efa67a0>) ("*None*" "23saf\Pasdc\P23dc" "*None*") (-1971.97 -379.973 0.0))

(AQX:PICK-ANNO NIL)            Pick MTEXT with Field
((<Entity name: 7efa67a0> <Entity name: 7efa67a0>)
("*None*" "23WALLsaf" "23%<\\AcObjProp Object(%<\\_ObjIdx 2130339688>%).Layer>%saf") (-1971.97 -379.973 0.0))

(AQX:PICK-ANNO NIL)            Pick ATTRIB without Field
((<Entity name: 7efa6770> <Entity name: 7efa6768>) ("DIMH" "11.000" "*None*") (514.699 273.557 0.0))

Argument 1 ENAME The given point
Return SUCCESS The annotation data list contains three parts:
  • A list of picked annotation object and its parent object.
    (NestObject[ENAME]     ParentObject[ENAME])
  • A list of of TagString, ContentString and FieldcodeString. If any of TagString or FieldcodeString is empty, use "*None*". If not a valid annotation is picked, use ( "*None*" "*None*" "*None*")
    (TagString[STR]     ContentString[STR]     FieldcodeString[STR])
  • The given point or user picked point.
    (XCoordinate[REAL]     YCoordinate[REAL]     ZCoordinate[REAL])
FAILURE "*None*"
AQX:PICK-CELL
(AQX:PICK-CELL GivenPoint)
Get the AcDbTable cell content data by a given/picked point inside the cell.
If given point is not available, prompt users to pick one.

(AQX:PICK-CELL NIL)           MTEXT content
((<Entity name: 7efa6730> <Entity name: 7efa6730>) ("*None*" "asfdasf" "*None*") (35.45 51.688 0.0))

(AQX:PICK-CELL NIL)           MTEXT content with Field
(<Entity name: 7efa6738> 1 0 ("asAcDbCirclead"  "as%<\\AcObjProp Object(%<\\_ObjIdx 2130339968>%).ObjectName>%ad"))

(AQX:PICK-CELL NIL)            Block content
(<Entity name: 7efa6738> 1 0 (nil nil))

(AQX:PICK-CELL NIL)            Block content with ATTRIB
(<Entity name: 7efa6738> 1 0 (("DIMH" . "0.000") ("NAME" . "ROOM")))

Argument 1 ENAME The given point
Return SUCCESS The cell annotation data list contains four parts:
  • [ENAME]    The parent AcDbTable object.
  • [INT]            The row ID integer
  • [INT]            The column ID integer
  • [LIST]          A string list, varies by different cell types
    • AcTextCell
      2-items list of (DisplayContent[STR] ContentFieldString[STR])
      If ContentFieldString is empty, use "*None*".
    • AcBlockCell without attribute(s)
      (NIL NIL)
    • AcBlockCell with attribute(s)
      The given point or user picked point
FAILURE "*None*"
AQX:PUTCONTENT
(AQX:PUTCONTENT AnnotationObject NewContentStringOrStringList)
Put new content to certain annotation object. (StringList used for multiple line content)

(AQX:PUTCONTENT obj '("asfqwe" "Kdasfasf:"))
<Entity name: 2250210>

Argument 1 ENAME The annotation object.
Argument 2 STR/LIST The new content string or string list(used for multiple line content).
Return SUCCESS The annotation object with new content.
FAILURE "*None*"
AQX:PUTCONTENT-CELL
(AQX:PUTCONTENT-CELL AcDbTableObject RowID ColumnID NewContentStringOrStringList)
Put content to certain AcTextCell or attribute of AcBlockCell.

(AQX:PUTCONTENT-CELL obj 2 5 '(("NAME" . "Room1")))
<Entity name: 2a5e210>

Argument 1 ENAME The AcDbTable object.
Argument 2 STR/LIST The Row ID integer, NIL for 0.
Argument 3 ENAME The ColumnID integer, NIL for 0.
Argument 4 STR/LIST The new content string for AcTectCell or tag-value list for attribute of AcBlockCell
Return SUCCESS Table object with new content
FAILURE "*None*"
AQX:SELATTRIBUTES
(AQX:SELATTRIBUTES SelectionSetRange MatchedBlockNameString MatchedTagString)
Advanced attributes selection.

(AQX:SELATTRIBUTES nil nil nil)
(<Entity name: 2250210> <Entity name: 2250250>... <Entity name: 22502d0>)

(AQX:SELATTRIBUTES ":model" "Blo*,a$*" "A*,*C")
(<Entity name: 38506e0><Entity name: 3850910> ...<Entity name: 38506d0>) 

Argument 1 PICKSET
STR

 

The selectionset of blocks (contain attributes). Some string IDs to use:
  • ":SEL" or NIL
    Prompt users to select blocks then filter out the attributes.
  • ":ALL"
    Automatically select from the entire drawing (model and all layouts).
  • ":LAYOUTNAME1:LAYOUTNAME2"
    Use ":" + Layout name string to indicate the layout to select from.
Argument 2 STR The block name to match, wildchar is supported, see detail in wcmatch function.
NIL for all blocks, as well as use "*".
Argument 3 STR The tag string to match, wildchar is supported, see detail in wcmatch function.
NIL for all blocks, as well as use "*".
Return SUCCESS The field code string.
FAILURE "*None*"
AQX:VFILL-CELL
(AQX:VFILL-CELL AcDbTableObject StartCellRow StartCellColumn EndCellRow EndCellColumn ACIColor)
Virtual fill the AcDbTable cells by colored GRDRAW points.
This function will fill all the cell ranges by two corner cells (Top-Left and Right-Bottom), if only one cell to be filled, please set the two cell IDs to be same.

(AQX:VFILL-CELL (car (entsel)) 0 7 nil 5 12)
NIL

(AQX:VFILL-CELL (car (entsel)) nil nil 7 5 nil)
NIL

Argument 1 ENAME The AcDbTable object.
Argument 2 INT The start cell row number. NIL for first cell
Argument 3 INT The start cell column number. NIL for first cell
Argument 4 INT The end cell row number. NIL for last cell
Argument 5 INT The end cell column number. NIL for last cell
Argument 6 INT The color of GRDRAW points. NIL for ACI gray color 8.
Return SUCCESS NIL
FAILURE NIL

AnnoQuarX: Sample Codes

        The following is a very simple codes to demonstrate how to use AnnoQuarX's powerful functions to exchange the contents of two picked annotations of any valid type recognized by AnnoQuarX. We can see that powered by AnnoQuarX, we can access various annotations with same and simple codes. By using this sample command, we no need to care the annotation type and position. The program can always get the result we want if we correctly picked the two annotations.

  (Defun C:SWAPCONTENT (/         obj1   obj2   obx1    obx2   fld1       fld2
                    str1   str2   tbl1   tbl2        row1   row2     col1  col2   tag1   tag2)
  (if (and (princ "\n Please pick First annotation <Exit>:")
          (setq obj1 (AQX:Pick-Anno nil))
          (setq str1 (cadr (cadr obj1))
                tag1 (car (cadr obj1))
                fld1 (nth 2 (cadr obj1))
                fld1 (if (/= fld1 "*None*") fld1 str1)
                obx1 (last (car obj1))
                obj1 (caar obj1)
          )
          (null (redraw obj1 3))
          (princ "\r Please pick the swap annotation <Exit>:")
          (setq obj2 (AQX:Pick-Anno nil))
          (setq str2 (cadr (cadr obj2))
                tag2 (car (cadr obj2))
                fld2 (nth 2 (cadr obj2))
                fld2 (if (/= fld2 "*None*") fld2 str2)
                obx2 (last (car obj2))
                obj2 (caar obj2)
          )
      )
    (progn
      (redraw obj1 4)
      (cond ((= (cdr (assoc 0 (entget obx1))) "ACAD_TABLE")
            (setq str1 (cdr (AQX:GETCELLID obj1)))
            (if (/= tag1 "*None*") (setq fld2 (list (cons tag1 fld2))))
           )
           ((= (cdr (assoc 0 (entget obj1))) "MULTILEADER")
            (if (/= tag1 "*None*") (setq fld2 (list (cons tag1 fld2))))
           )
      )
      (cond ((= (cdr (assoc 0 (entget obx2))) "ACAD_TABLE")
            (setq str2 (cdr (AQX:GETCELLID obj2)))
            (if (/= tag2 "*None*") (setq fld1 (list (cons tag2 fld1))))
           )
           ((= (cdr (assoc 0 (entget obj2))) "MULTILEADER")
            (if (/= tag2 "*None*") (setq fld1 (list (cons tag2 fld1))))
           )
      )
      (if (= (type str1) 'list)
       (AQX:PUTCONTENT-CELL obx1 (car str1) (cadr str1) fld2)
       (AQX:PUTCONTENT obj1 fld2)
      )
      (if (= (type str2) 'list)
       (AQX:PUTCONTENT-CELL obx2 (car str2) (cadr str2) fld1)
       (AQX:PUTCONTENT obj2 fld1)
      )
      (if (= (cdr (assoc 0 (entget obx1))) "INSERT")(repeat 2 (entdel obx1)))
      (if (= (cdr (assoc 0 (entget obx2))) "INSERT")(repeat 2 (entdel obx2)))
    )
  )
  (princ)
)
 

//Koz Jono Yeoh//

Copyright(C) 1994-2009 KozMos Inc
All rights reserved.