TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Crank on July 26, 2008, 10:55:21 AM
-
I'm trying to find the annotative scales of a selected entity.
With this code the scales for most entities can be found:
(defun get_all_scales (ent / annotative lijst n schalen)
(setq annotative (cdr (assoc 360 ent)))
(if annotative (progn
(setq lijst (entget (cdr (assoc 350 (entget (cdr (assoc 360 (entget annotative))))))))
(foreach n (collect 350 lijst)
(setq schalen (cons
(cdr (assoc 300 (entget (cdr (assoc 340 (entget n))))))
schalen
)
)
)
schalen
))
)
(defun collect (key lijst / n return)
(foreach n lijst
(if (= key (car n))
(setq return (cons (cdr n) return))
)
)
return
)
(defun c:test (/ ent scalelist)
(setq ent (entget (car (entsel))))
(if ent (setq scalelist (get_all_scales ent)))
(if scalelist
(princ scalelist)
;else
(alert "\nNo annoscales")
)
(princ)
)
However, on dynamic blocks it crashes, because group 350 isn't present.
No problem, it's possible to make an exeption for dynamic blocks, but where is the data stored of the annotative scales? I can't find it... Perhaps someone can point me in the right direction.
Any help is appriciated.
-
Found it :-)
Annotative dynamic blocks do have two 360-groups. You need the one that belongs to AcDbContextDataManager, so you can use:
(defun get_ent_scales (ent / annotative lijst n schalen collect)
(defun collect (key lijst / n return)
(foreach n lijst
(if (= key (car n))
(setq return (cons (cdr n) return))
)
)
return
)
(setq annotative (cdr (assoc 360 ent)))
(if annotative (progn
(setq lijst
(entget (cdr (assoc 350
(entget (cdr (assoc 360
[color=red](member '(3 . "AcDbContextDataManager")[/color][color=green]; Get the right 360-code[/color]
(entget annotative)
[color=red])[/color]
)))
)))
)
(foreach n (collect 350 lijst)
(setq schalen
(cons
(cdr (assoc 300 (entget (cdr (assoc 340 (entget n))))))
schalen
)
)
)
schalen
))
)
-
You can to retrieve "ACDB_ANNOTATIONSCALES" dictionary of block and walk around XRecords:
(defun Get_Annotation_Dictionary(vlaObj / aDic)
(if(= :vlax-true
(vla-get-HasExtensionDictionary vlaObj))
(progn
(vlax-for d(vla-GetExtensionDictionary vlaObj)
(if(and
(vlax-property-available-p d 'Name)
(= "ACDB_ANNOTATIONSCALES"(vla-get-Name d))
); end and
(setq aDic d)
); end if
); end vlax-for
); end progn
); end if
aDic
); end of Get_Annotation_Dictionary
-
Thanks ASMI,
Though I already solved it in ALISP, I wanted to try yours.
I don't know much about VLISP, but when I use:
(defun c:test (/ obj lijst)
(setq obj (vlax-ename->vla-object (car (entsel))))
(setq lijst (Get_Annotation_Dictionary obj))
)
I always get nil as the result. What am I doing wrong?
-
Hi Crank,
ASMI left out a step it appears. This gets the correct Dictionary:
(defun Get_Annotation_Dictionary (vlaObj / aDic)
(if(= :vlax-true
(vla-get-HasExtensionDictionary vlaObj))
(progn
(vlax-for d(vla-GetExtensionDictionary vlaObj)
(if(and
(vlax-property-available-p d 'Name)
(= "AcDbContextDataManager" (vla-get-Name d))
); end and
(vlax-for e d
(if (and
(vlax-property-available-p e 'Name)
(= "ACDB_ANNOTATIONSCALES" (vla-get-Name e))
)
(setq aDic e)
)
)
); end if
); end vlax-for
); end progn
); end if
aDic
); end of Get_Annotation_Dictionary
However, the resulting objects don't seem to be exposed enough in the API for what you want:
; IAcadObject: The standard interface for a basic AutoCAD object
; Property values:
; Application (RO) = #<VLA-OBJECT IAcadApplication 00d74d3c>
; Document (RO) = #<VLA-OBJECT IAcadDocument 092a2c10>
; Handle (RO) = "369C"
; HasExtensionDictionary (RO) = 0
; ObjectID (RO) = 2125842016
; ObjectName (RO) = "AcDbBlkRefObjectContextData"
; OwnerID (RO) = 2125841792
; Methods supported:
; Delete ()
; GetExtensionDictionary ()
; GetXData (3)
; SetXData (2)
-
Thanks Jeff, that works.
It's good to have this by the side. Annoscales aren't documented in the DXF-manual and it wouldn't surprise me if Autodesk desides to do it different in a next release.
-
However, the resulting objects don't seem to be exposed enough in the API for what you want:
Need to extract XRecords. I do not want to make it long ActiveX way and use (vlax-vla-object->ename.
(defun Get_Ann_Scales_List(vlaObj / aDic oLst)
(if(= :vlax-true
(vla-get-HasExtensionDictionary vlaObj))
(progn
(vlax-for d(vla-GetExtensionDictionary vlaObj)
(if(and
(vlax-property-available-p d 'Name)
(= "AcDbContextDataManager"(vla-get-Name d))
); end and
(setq aDic(vla-Item d "ACDB_ANNOTATIONSCALES"))
); end if
); end vlax-for
(if aDic
(progn
(vlax-for i aDic
(setq oLst(cons
(cdr
(assoc 42
(entget
(vlax-vla-object->ename i))))oLst))
); end vlax-for
); end progn
); end if
); end progn
); end if
oLst
); end of Get_Ann_Scales_List
Usage:
(Get_Ann_Scales_List(vlax-ename->vla-object(car(entsel))))
(4.0 2.0 1.0)
DXF lists for (vlax-vla-object->ename i):
Scale = 1
((-1 . <Entity name: 79cbad10>) (0 . "ACDB_BLKREFOBJECTCONTEXTDATA_CLASS") (5 . "45A") (102 . "{ACAD_REACTORS") (330 . <Entity name: 79cbad08>) (102 . "}") (330 . <Entity name: 79cbad08>) (100 . "AcDbObjectContextData") (70 . 3) (290 . 1) (100 . "AcDbAnnotScaleObjectContextData") (340 . <Entity name: 7c0700e0>) (50 . 0.0) (10 960.372 265.841 0.0) (41 . 1.0)(42 . 1.0) (43 . 1.0))
Scale = 2
((-1 . <Entity name: 79c114c0>) (0 . "ACDB_BLKREFOBJECTCONTEXTDATA_CLASS") (5 . "540") (102 . "{ACAD_REACTORS") (330 . <Entity name: 79cbad08>) (102 . "}") (330 . <Entity name: 79cbad08>) (100 . "AcDbObjectContextData") (70 . 3) (290 . 0) (100 . "AcDbAnnotScaleObjectContextData") (340 . <Entity name: 7c0700e8>) (50 . 0.0) (10 960.372 265.841 0.0) (41 . 2.0) (42 . 2.0) (43 . 2.0))
Scale = 4
((-1 . <Entity name: 79c114d0>) (0 . "ACDB_BLKREFOBJECTCONTEXTDATA_CLASS") (5 . "542") (102 . "{ACAD_REACTORS") (330 . <Entity name: 79cbad08>) (102 . "}") (330 . <Entity name: 79cbad08>) (100 . "AcDbObjectContextData") (70 . 3) (290 . 0) (100 . "AcDbAnnotScaleObjectContextData") (340 . <Entity name: 7c0700f0>) (50 . 0.0) (10 960.372 265.841 0.0) (41 . 4.0) (42 . 4.0) (43 . 4.0))