明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: 明经通道

关于作者

    [复制链接]
发表于 2014-6-5 15:55 | 显示全部楼层
正常程序员的生活啊,问题是为什么有四个孩子?
发表于 2017-11-23 15:00 | 显示全部楼层
万丈高楼平地起,向前辈看齐
发表于 2018-8-19 21:20 | 显示全部楼层
有趣的作者
发表于 2019-1-13 22:25 | 显示全部楼层
大神都是从小兵磨练而来的
发表于 2019-8-22 14:15 | 显示全部楼层
学习了,谢谢大佬
回复 支持 1 反对 0

使用道具 举报

发表于 2020-11-30 15:55 | 显示全部楼层
4个娃,工作之余还有时间带娃,楼主很厉害,娃有个好父亲。
发表于 2021-11-10 15:59 | 显示全部楼层
第15章- XDATA and XRECORDs
发表于 2021-11-10 15:59 | 显示全部楼层
第15章- XDATA and XRECORDs

AutoCAD提供了几种在图形中存储非图形化信息的方法。这可以包括各种数据类型,例如数字、文本等等。其中两个最常见的是扩展实体数据Extended Entity Data(EED)和字典Dictionaries。最常见的EED的形式是XDATA,它是所有图形实体以及表格对象的扩展,例如图层和线型。这允许您在(非图形的)实体或表对象中存储隐藏的信息,必要时检索这些信息。
另一种存储非图形化信息的方式是使用XRECORD对象。XRECORD对象是Document对象的一部分,允许您在字典集合中存储字符串信息。
使用XDATA的优点是信息附加到特定的实体或表成员后面。使用XRECORD对象的优点是它们被附加到文档本身,而不是任何特定的实体或表对象。此外,XDATA对可以存储在给定实体或表对象上的数据大小有一定的限制。XRECORD对象对数据存储没有任何大小限制,但是会影响DWG文件大小,以及打开图形时的内存需求。
使用扩展数据XDATA
扩展数据可以附着或检索图形中的任何图元,以及诸多表对象(例如图层、布局和线型)。XDATA根据数据类型分别存储信息,因此无论何时将信息附加到对象,还是尝试检索信息时,都必须知道要存储的信息类型。例如,如果将整数值附加到实体,却尝试将其作为字符串值检索,则不会得到所需的结果。
使用XRECORD对象
XRECORD对象作为字典进行维护,这意味着它们具有唯一的名称,并且可以通过该名称进行访问。它们附加到文档本身,而不是像扩展数据那样附加到任何图形对象或表对象。如果图形被保存回R12,或者转换为不支持XRECORD的其他CAD格式,XRECORD 对象将消失。
由于XRECORD对象附加到文档,因此用户不会随意删除它们。例如,如果将XDATA附加到一个层,而该层被清除,那么XDATA也将被删除。您可以将XDATA附着到“0”层以避免现这种情况,然而XDATA存储的数据类型和数据大小仍然受到限制。
Xrecords只能创建、重命名或删除。没有直接的方法来修改它们。修改Xrecord的唯一方法是检索到其内容,从dictionary对象中删除他们,然后重新创建新的Xrecord。以下函数演示了如何使用AutoLISP执行此操作。
(defun Xrecord-Rebuild (name dat)
  (Xrecord-Delete name)
  (Xrecord-Add name dat)
)
(defun Xrecord-Get (name / xlist)
  (if (setq xlist (dictsearch (namedobjdict) name))
    (cdr (assoc 1 xlist))
  )
)
(defun Xrecord-Delete (name)
  (dictremove (namedobjdict) name)        ; remove from dictionary
)
(defun Xrecord-Add (name sdata / xrec xname)
  (setq        xrec
         (list
           (cons 0 "XRECORD")
           (cons 100 "AcDbXrecord")
           (cons 1 sdata)
           (cons 62 1)
         )
  )
  (setq xname (entmakex xrec))                        ; rebuild xrecord
  (dictadd (namedobjdict) name xname)        ; return to dictionary
  (princ)
)
上述表单的问题在于,它使用(entmake),当与某些其他ActiveX函数混合使用时,有时会在AutoCAD中导致问题。更合适的形式是ActiveX方法,如下例所示。
(vl-load-com)
(defun Xrecord-Rebuild (dict name data)
  (Xrecord-Delete dict name)
  (Xrecord-Add dict name data)
)
(defun Xrecord-Get  (dict name / acad doc dcs odc xrec #typ #dat out)
  (setq        acad (vlax-get-acad-object)
        doc  (vla-get-activedocument acad)
        dcs  (vla-get-dictionaries doc)
  )
  (cond
    ((setq odc (dsx-item dcs dict))
     (cond
       ((setq xrec (dsx-item odc name))
            (vla-getXrecordData xrec '#typ '#dat)
            (setq #typ (vlax-safearray->list #typ)
                 #dat (vlax-safearray->list #dat)
             )
             (setq out (mapcar 'vlax-variant-value #dat))
             (vlax-release-object odc)
       )
     )
     (vlax-release-object dcs)
    )
  )
  out
)

(defun Xrecord-Delete (dict name / dcs odc xr)
  (setq dcs (vla-get-dictionaries active-doc))
  (cond
    ((setq odc (dsx-item dcs dict))
     (cond
       ((setq xr (dsx-item odc name))
        (vla-delete xr)
        (vlax-release-object xr)
       )
     )
     (vlax-release-object odc)
    )
  )
  (vlax-release-object dcs)
)

(defun Xrecord-Add
  (dict name data / acad doc dicts dict xrec #typ #dat)
  (setq        acad  (vlax-get-acad-object)
        doc   (vla-get-activedocument acad)
        dicts (vla-get-Dictionaries doc)
        dict  (vlax-invoke-method dicts "Add" dict)
        xrec  (vla-AddXrecord dict name)
  )
  (if (not (listp data))
    (setq data (list data))
  )                                        ; ensure list!
  (vla-setXrecordData
    xrec
    (List->VariantArray
      (List->IntList data)
      'vlax-vbInteger
    )
    (List->VariantArray data 'vlax-vbVariant)
  )
  (vla-getXrecordData xrec '#typ '#dat)
  (setq        #typ (vlax-safearray->list #typ)
        #dat (vlax-safearray->list #dat)
  )
  (mapcar 'vlax-variant-value #dat)
)
两个函数(List->VariantArray)和(List->IntList)分别用于定义安全数组safearray的内容和维度。显然,它们的用途远不止这些。(List->VariantArray)的第二个参数必须是单引号的ActiveX数据类型声明,如’vlax-vbString。
(defun List->VariantArray (lst datatype / arraySpace sArray)
  (setq        arraySpace
         (vlax-make-safearray
           (eval datatype)
           (cons 0 (1- (length lst)))
         )
  )
  (setq sArray (vlax-safearray-fill arraySpace lst))
  (vlax-make-variant sArray)
)
(defun List->IntList (lst / n)
  (setq n 0)
  (mapcar (function (lambda (x) (setq n (1+ n)))) lst)
)
另一个函数(dsx-item)用来使用集合的item方法获取(或尝试获取)项。此函数包括在获取失败时捕获错误,这将返回ActiveX错误,而不是像nil这样的错误。在这种情况下,我们捕获一个错误,如果获取失败,则返回nil。否则,我们将从集合中返回对象。
(defun DSX-Item (collection item / out)
  (if
    (not
      (vl-catch-all-error-p
        (setq out
               (vl-catch-all-apply 'vla-item (list collection item))
        )
      )
    )
     out                                ; return object or nil
  )
)
为了演示如何使用这些东西,我们将在当前图形中保存一个Xrecord,其中包含一些信息,例如当前用户名(假设我们使用的是Windows NT、2000或XP)和一些其他信息。
(setq username (getenv “username")        ; logged on user ID
      machine  (getenv “computername") ; NETBIOS computer name
)
(Xrecord-Rebuild "PERSONAL" "UserData" (list username machine))
_$ Returns ("DSTEIN1234" "W2K-1234")
(Xrecord-Get "PERSONAL" "UserData")
_$Returns ("DSTEIN1234" "W2K-1234")
(Xrecord-Rebuild "PERSONAL" "UserData" "1234")
_$Returns ("1234")
那么,你能用Xrecords做什么呢?什么都行。它们对于在图形中存储信息非常有用,因为图形中的信息不直接绑定到任何特定实体或表。如果您习惯于在扩展数据中存储信息,那么您可能知道,如果删除了实体或表项,扩展数据就会丢失。当然,您可以将扩展数据附加到像“0”层之类的东西上,这样它就永远不会被删除。但是,Xdata受到内容限制,可以用Xrecords来减轻这些限制。
发表于 2022-6-8 08:40 | 显示全部楼层
学习了,谢谢大佬
发表于 2023-4-6 15:39 | 显示全部楼层
文化传承  对作者表示由衷敬佩  是我辈学习的目标和方向
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-17 01:18 , Processed in 0.143054 second(s), 16 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表