Grrr 发表于 2022-7-5 17:06:46

GroupLayerFil之间的关系

嗨,伙计们
我的问题可能相当复杂,所以我希望有人能回答:
有人知道组层过滤器和层之间的编程关系吗或者我在哪里可以找到它?
 
我已经找到了组层过滤器的位置(使用VLAX),
但我认为目前关于他们的唯一有用信息是他们的名字。
它们中的每一个不应该都有一个层数的“计数”属性吗?
或者至少每个层对象都与其所在的组层过滤器有一些连接信息(方法或属性)。
 

 
为了找到我抛弃的任何关系:
-图层集合,
-图层集合扩展Dict,
-Layers collection Extended Dict中的每一项,
-“ACAD_LAYERFILTERS”集合(位于Layers Coll Extended Dict内),
-“ACAD_LAYERFILTERS”系列中的每一项,
-活动层,
-活动层的扩展Dict
 
以下是使用(C:ForTest)的示例图:
分组层过滤器测试。图纸
 
以下是我使用VLIDE控制台获得的(缩短的)信息:

; Helper functions:
(defun DT ( o / ) (if (= (type o) 'VLA-OBJECT) (vlax-dump-object o T))) ; Dump True (I'm using it as a shortcut)
(defun GetExtDict ( o / ) (if (and (= (type o) 'VLA-OBJECT) (vlax-method-applicable-p o 'GetExtensionDictionary)) (vlax-invoke o 'GetExtensionDictionary)))
(defun DTColl ( coll / ) (if (= (type coll) 'VLA-OBJECT) (vlax-for o coll (vlax-dump-object o T)))) ; Dump True (everything inside of a collection)
(defun Coll->Lst ( #Collection / Lst ) (vlax-for o #Collection (setq Lst (cons o Lst))) (reverse Lst)); convert Collection into List

; Start digging:
(setq AcLay (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))))
(setq ExtDictAcLay (GetExtDict AcLay))
(setq LayColl (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
(setq ExtDictCollOfLayersColl (GetExtDict LayColl))
; (DTColl ExtDictCollOfLayersColl) ; inside of it there are: ACAD_LAYERFILTERS ACAD_LAYERSTATES ACLYDICTIONARY
(setq LAYERFILTERS (vla-item ExtDictCollOfLayersColl "ACAD_LAYERFILTERS"))
(setq LAYERSTATES (vla-item ExtDictCollOfLayersColl "ACAD_LAYERSTATES"))
(setq ACLYDICTIONARY (vla-item ExtDictCollOfLayersColl "ACLYDICTIONARY"))

_$ (DTcoll LAYERFILTERS)
; IAcadXRecord: XRecord objects are used to store and manage arbitrary data
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00007ff78a999110>
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0000002a7ec52b78>
;   Handle (RO) = "20C"
;   HasExtensionDictionary (RO) = 0
;   Name = "Group1"
;   ObjectID (RO) = 42
;   ObjectName (RO) = "AcDbXrecord"
;   OwnerID (RO) = 43
;   TranslateIDs = -1
; Methods supported:
;   Delete ()
;   GetExtensionDictionary ()
;   GetXData (3)
;   GetXRecordData (2)
;   SetXData (2)
;   SetXRecordData (2)

; IAcadXRecord: XRecord objects are used to store and manage arbitrary data
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00007ff78a999110>
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0000002a7ec52b78>
;   Handle (RO) = "20E"
;   HasExtensionDictionary (RO) = 0
;   Name = "Group2"
;   ObjectID (RO) = 44
;   ObjectName (RO) = "AcDbXrecord"
;   OwnerID (RO) = 43
;   TranslateIDs = -1
; Methods supported:
;   Delete ()
;   GetExtensionDictionary ()
;   GetXData (3)
;   GetXRecordData (2)
;   SetXData (2)
;   SetXRecordData (2)

; IAcadXRecord: XRecord objects are used to store and manage arbitrary data
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00007ff78a999110>
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0000002a7ec52b78>
;   Handle (RO) = "210"
;   HasExtensionDictionary (RO) = 0
;   Name = "Group3"
;   ObjectID (RO) = 45
;   ObjectName (RO) = "AcDbXrecord"
;   OwnerID (RO) = 43
;   TranslateIDs = -1
; Methods supported:
;   Delete ()
;   GetExtensionDictionary ()
;   GetXData (3)
;   GetXRecordData (2)
;   SetXData (2)
;   SetXRecordData (2)

; IAcadXRecord: XRecord objects are used to store and manage arbitrary data
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00007ff78a999110>
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0000002a7ec52b78>
;   Handle (RO) = "212"
;   HasExtensionDictionary (RO) = 0
;   Name = "Group4"
;   ObjectID (RO) = 46
;   ObjectName (RO) = "AcDbXrecord"
;   OwnerID (RO) = 43
;   TranslateIDs = -1
; Methods supported:
;   Delete ()
;   GetExtensionDictionary ()
;   GetXData (3)
;   GetXRecordData (2)
;   SetXData (2)
;   SetXRecordData (2)
T
_$

你可以试着用上面的句子来“挖掘”/检查。
 
如果无法打开dwg,请使用以下测试代码重新创建组图层过滤器和图层测试dwg:

; To create the test Layers with their LayerGroupFilters:
(defun C:ForTest ( / LayGroupNames LayLstGroup1 LayLstGroup2 LayLstGroup3 LayLstGroup4 n)

(defun CreateLayer ( #Name / )
        (entmake
                (list
                        (cons 0 "LAYER")
                        (cons 100 "AcDbSymbolTableRecord")
                        (cons 100 "AcDbLayerTableRecord")
                        (cons 2 #Name)
                        (cons 70 0)
                )
        )
)

(setq LayGroupNames '("Group1" "Group2" "Group3" "Group4"))
(setq
        LayLstGroup1 '("Group1-Lay1" "Group1-Lay2" "Group1-Lay3" "Group1-Lay4" "Group1-Lay5" "Group1-Lay6" "Group1-Lay7")
        LayLstGroup2 '("Group2-Lay1" "Group2-Lay2" "Group2-Lay3" "Group2-Lay4" "Group2-Lay5" "Group2-Lay6" "Group2-Lay7")
        LayLstGroup3 '("Group3-Lay1" "Group3-Lay2" "Group3-Lay3" "Group3-Lay4" "Group3-Lay5" "Group3-Lay6" "Group3-Lay7")
        LayLstGroup4 '("Group4-Lay1" "Group4-Lay2" "Group4-Lay3" "Group4-Lay4" "Group4-Lay5" "Group4-Lay6" "Group4-Lay7")
)

(setq n 0)
(foreach x (list LayLstGroup1 LayLstGroup2 LayLstGroup3 LayLstGroup4)
        (mapcar 'CreateLayer x)
        (command "._-layer" "filter" "new" "property" "All" (strcat "NAME==\"" (nth n LayGroupNames) "*\"") (nth n LayGroupNames) "X" nil)
        (setq n (1+ n))
)

(princ)
); defun C:ForTest

 
原因是我对AUGI论坛上的“一个简单请求”的帖子很好奇。
用户询问是否可以重命名一组特定图层,方法是添加它们所在图层组过滤器名称的前缀。
然而,这不是我的目标。

Grrr 发表于 2022-7-5 17:22:03

可以今天我做了一个小进步:
(defun C:test ( / ld AllLyrNames LayersColl LFtContainer MyLayerFilterNames Lst FtsLst)

(while (setq ld (tblnext "LAYER" (not ld)))
        (setq AllLyrNames (cons (cdr (assoc 2 ld)) AllLyrNames))
)

(setq LayersColl (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
(setq LFtContainer (vla-item (vla-GetExtensionDictionary LayersColl) "ACAD_LAYERFILTERS"))
(vlax-map-collection LFtContainer '(lambda (x) (setq MyLayerFilterNames (cons (vla-get-Name x) MyLayerFilterNames))))

; (if MyLayerFilterNames
; (foreach x (reverse MyLayerFilterNames)
; (print (HowMyLayerFilterIsCreated x))
; )
; )

(if MyLayerFilterNames
        (progn
                (if (not Lst) (setq Lst (list)))
                (setq FtsLst (mapcar 'HowMyLayerFilterIsCreated MyLayerFilterNames))
                (foreach Ft FtsLst
                        (setq Lst (append Lst (mapcar '(lambda (x) (if (wcmatch x (cadr Ft)) (cons (car Ft) x))) AllLyrNames)))
                )
                (setq Lst (reverse (vl-remove nil Lst)))
                (foreach x Lst (print x))
        )
); if MyLayerFilterNames

(princ)
); defun C:test

(defun HowMyLayerFilterIsCreated ( LyrFilterName / LayersColl LFtContainer MyLayerFilter XRecordDataLst MyLayerFilterXRecordDataType MyLayerFilterXRecordData )
(if
        (and
                (setq LayersColl (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
                (setq LFtContainer (vla-item (vla-GetExtensionDictionary LayersColl) "ACAD_LAYERFILTERS"))
                (setq MyLayerFilter (vla-item LFtContainer LyrFilterName))
        )
        (progn
                (vla-GetXRecordData MyLayerFilter 'MyLayerFilterXRecordDataType 'MyLayerFilterXRecordData)
                (setq XRecordDataLst (mapcar 'vlax-variant-value (vlax-safearray->list MyLayerFilterXRecordData)))
        )
)
XRecordDataLst
);| defun HowMyLayerFilterIsCreated |; (or (vlax-get-acad-object) (vl-load-com))
随附上述打印结果。dwg如下所示:
Command: TEST
("Group1" . "Group1-Lay1")
("Group1" . "Group1-Lay2")
("Group1" . "Group1-Lay3")
("Group1" . "Group1-Lay4")
("Group1" . "Group1-Lay5")
("Group1" . "Group1-Lay6")
("Group1" . "Group1-Lay7")
("Group2" . "Group2-Lay1")
("Group2" . "Group2-Lay2")
("Group2" . "Group2-Lay3")
("Group2" . "Group2-Lay4")
("Group2" . "Group2-Lay5")
("Group2" . "Group2-Lay6")
("Group2" . "Group2-Lay7")
("Group3" . "Group3-Lay1")
("Group3" . "Group3-Lay2")
("Group3" . "Group3-Lay3")
("Group3" . "Group3-Lay4")
("Group3" . "Group3-Lay5")
("Group3" . "Group3-Lay6")
("Group3" . "Group3-Lay7")
("Group4" . "Group4-Lay1")
("Group4" . "Group4-Lay2")
("Group4" . "Group4-Lay3")
("Group4" . "Group4-Lay4")
("Group4" . "Group4-Lay5")
("Group4" . "Group4-Lay6")
("Group4" . "Group4-Lay7")
我只需要弄清楚如何这样构造Lst报价:

'("Group1" . '("Group1-Lay1" "Group1-Lay2" "Group1-Lay3" "Group1-Lay5" "Group1-Lay6" "Group1-Lay7"))
'("Group2" . '("Group2-Lay1" "Group2-Lay2" "Group2-Lay3" "Group2-Lay5" "Group2-Lay6" "Group2-Lay7"))
'("Group3" . '("Group3-Lay1" "Group3-Lay2" "Group3-Lay3" "Group3-Lay5" "Group3-Lay6" "Group3-Lay7"))
'("Group4" . '("Group4-Lay1" "Group4-Lay2" "Group4-Lay3" "Group4-Lay5" "Group4-Lay6" "Group4-Lay7"))

所以它会更可读(至少对我来说)。

BIGAL 发表于 2022-7-5 17:28:45

也许向后看一下车=group1将“group1 layername”添加到临时“lstemp”获取下一个if=group1将“group1 layername”添加到“lstemp”继续。一旦group1/=group2,创建新的层group1列表(“group1”。(lstemp))将lstemp替换为nil,并对group2进行agian。希望它有意义。
 

groupname = "Group1"
lsttemp = ("Group1-Lay1" "Group1-Lay2" "Group1-Lay3" "Group1-Lay5" "Group1-Lay6" "Group1-Lay7"))

Roy_043 发表于 2022-7-5 17:44:59

图形中的图层过滤器真的是“组过滤器”吗?我不能确定,因为BricsCAD只支持图层特性过滤器,但图形中的过滤器似乎就是这种类型。

Grrr 发表于 2022-7-5 17:55:48

是的,BIGAL,我正在考虑类似的事情,但也许我可以再回头,修改“Lst”创建以适应我之前的发现(来自上面代码的注释部分):
(defun C:test ( / LayersColl LFtContainer MyLayerFilterNames )

(setq LayersColl (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
(setq LFtContainer (vla-item (vla-GetExtensionDictionary LayersColl) "ACAD_LAYERFILTERS"))
(vlax-map-collection LFtContainer '(lambda (x) (setq MyLayerFilterNames (cons (vla-get-Name x) MyLayerFilterNames))))

(if MyLayerFilterNames
        (foreach x (reverse MyLayerFilterNames)
                (print (HowMyLayerFilterIsCreated x))
        )
)

(princ)
); defun C:test

(defun HowMyLayerFilterIsCreated ( LyrFilterName / LayersColl LFtContainer MyLayerFilter XRecordDataLst MyLayerFilterXRecordDataType MyLayerFilterXRecordData )
(if
        (and
                (setq LayersColl (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object))))
                (setq LFtContainer (vla-item (vla-GetExtensionDictionary LayersColl) "ACAD_LAYERFILTERS"))
                (setq MyLayerFilter (vla-item LFtContainer LyrFilterName))
        )
        (progn
                (vla-GetXRecordData MyLayerFilter 'MyLayerFilterXRecordDataType 'MyLayerFilterXRecordData)
                (setq XRecordDataLst (mapcar 'vlax-variant-value (vlax-safearray->list MyLayerFilterXRecordData)))
        )
)
XRecordDataLst
);| defun HowMyLayerFilterIsCreated |; (or (vlax-get-acad-object) (vl-load-com))
我得到了这个结果:
Command: TEST
("Group1" "Group1*" "*" "*" 0 "*" "*")
("Group2" "Group2*" "*" "*" 0 "*" "*")
("Group3" "Group3*" "*" "*" 0 "*" "*")
("Group4" "Group4*" "*" "*" 0 "*" "*")
也许用每个层名对cadr进行wcmatch,然后以某种方式与car(代表组名)进行对比。
我认为我的这些清单与这一行有关:

 
恐怕你是对的,罗伊,因为我正在使用这一行创建这些示例属性过滤器:
(command "._-layer" "filter" "new" "property" "All" (strcat "NAME==\"" (nth n LayGroupNames) "*\"") (nth n LayGroupNames) "X" nil)
我真的不知道这两者之间的区别:

但现在我看到,双击带有groupfilter名称的文件夹时,上面的对话框“Layer Filter Properties”只出现在创建的“Property”过滤器上,而不是“Group”过滤器上。
虽然我不确定我会为“群组”找到什么信息(HowMyLayerFilterIsCreated)。
我会进一步实验,至少我现在得到了我需要的“信息”。。。因此,这就成了一个列表构建/操作的问题。

Roy_043 发表于 2022-7-5 17:59:55

@Grrr:
如果项不在集合中,则item方法将出错:
您可以使用“vl catch all构造”来解决此问题:
(KGA_Sys_Apply 'vla-item (list (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) "DoesNotExist"))

;;; ======================================================================
;;; Lib function: KGA_Sys_Apply
;;; Purpose:      Shortcut for standard "vl-catch-all construction".
;;; Arguments:    expr   - Expression to evaluate.
;;;               varLst - List of variables.
;;; Return value: Varies. Note: A nil value can mean two things: there was
;;;               an error or the expression returned nil.
;;;               Use (KGA_Sys_ApplyAlt) if this is a problem.
;;; Remarks:      None.
;;; Examples:
;;; (KGA_Sys_Apply 'strcat '("a" "bb" "ccc" 1))      => nil
;;; (KGA_Sys_Apply 'strcat '("a" "bb" "ccc" "dddd")) => "abbcccdddd"
;;; ======================================================================
(defun KGA_Sys_Apply (expr varLst / ret)
(if (not (vl-catch-all-error-p (setq ret (vl-catch-all-apply expr varLst))))
   ret
)
)

;;; Similar to (KGA_Sys_Apply) but the return value is T or nil (there was an error).
(defun KGA_Sys_ApplyAlt (expr varLst)
(not (vl-catch-all-error-p (vl-catch-all-apply expr varLst)))
)

Grrr 发表于 2022-7-5 18:09:50

是的,罗伊,我忘了“错误陷阱”这些。我更喜欢这样:
; modeT - if is set to true: then the return would be 'T or nil, otherwise the returned value or nil
; Examples: ;;; (ErrCatch nil '/ '(4 2)) -> 2 ;;; (ErrCatch T '/ '(4 2)) -> T ;;; (ErrCatch nil '/ '(4 0)) -> nil ;;; (ErrCatch T '/ '(4 0)) -> nil ;;;
(defun ErrCatch ( modeT func varLst / rtn ) (if (not (vl-catch-all-error-p (setq rtn (vl-catch-all-apply func varLst)))) (if modeT 'T rtn)) )
例子:
12
谢谢
页: [1]
查看完整版本: GroupLayerFil之间的关系