Author Topic: Determine Dynamic Block Visibility Parameter  (Read 4067 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12923
  • London, England
Determine Dynamic Block Visibility Parameter
« on: August 24, 2011, 06:33:02 AM »
Is it possible to determine (using LISP) which dynamic block property object is the Visibility Parameter for the block?

Previously, I have used:

Code: [Select]
(car
  (vl-member-if
    (function
      (lambda ( a )
        (and
          (setq a (vlax-get a 'allowedvalues))
          (listp a)
          (vl-every '(lambda ( b ) (eq 'STR (type b))) a)
        )
      )
    )
    (vlax-invoke <VLA-object> 'getdynamicblockproperties)
  )
)

As used in this example to count dynamic blocks by Visibility state:

Code: [Select]
(defun c:dbcount ( / _Assoc++ _PadBetween lst prp ss ) ;; © Lee Mac 2011

  (defun _Assoc++ ( key alist )
    (
      (lambda ( pair )
        (if pair
          (subst (cons key (1+ (cdr pair))) pair alist)
          (cons  (cons key 1) alist)
        )
      )
      (assoc key alist)
    )
  )

  (defun _PadBetween ( s1 s2 ch ln )
    (
      (lambda ( a b c )
        (repeat (- ln (length b) (length c)) (setq c (cons a c)))
        (vl-list->string (append b c))
      )
      (ascii ch)
      (vl-string->list s1)
      (vl-string->list s2)
    )
  )

  (if (ssget "_X" (list '(0 . "INSERT") (cons 410 (getvar 'CTAB))))
    (progn
      (vlax-for obj
        (setq ss
          (vla-get-activeselectionset
            (vla-get-activedocument (vlax-get-acad-object))
          )
        )
        (if
          (and (eq :vlax-true (vla-get-isdynamicblock obj))
            (setq prp
              (car
                (vl-member-if
                  (function
                    (lambda ( a )
                      (and (setq a (vlax-get a 'allowedvalues)) (listp a)
                        (vl-every '(lambda ( b ) (eq 'STR (type b))) a)
                      )
                    )
                  )
                  (vlax-invoke obj 'getdynamicblockproperties)
                )
              )
            )
          )
          (setq lst (_Assoc++ (vlax-get prp 'value) lst))
        )
      )
      (vla-delete ss)
      (princ (_PadBetween "\nVisibility State" "Count" "." 41))
      (princ (_PadBetween "\n" "" "=" 41))
      (foreach x (vl-sort lst '(lambda ( a b ) (< (car a) (car b))))
        (princ (_PadBetween (strcat "\n" (car x)) (itoa (cdr x)) "." 41))
      )
      (textpage)
    )
  )
  (princ)
)
(vl-load-com) (princ)

However, this approach fails when the dynamic block has a Lookup parameter, so I wonder if someone knows a better way?

Any advice is appreciated.

Lee

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Determine Dynamic Block Visibility Parameter
« Reply #1 on: August 24, 2011, 06:39:42 AM »
Hi,

You may have a look here.
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12923
  • London, England
Re: Determine Dynamic Block Visibility Parameter
« Reply #2 on: August 24, 2011, 06:53:08 AM »
Thanks gile :-)

I notice that you use the UnitsType property, however, this has the same for both the Visibility Parameter and Lookup Parameter  :-(

Lee Mac

  • Seagull
  • Posts: 12923
  • London, England
Re: Determine Dynamic Block Visibility Parameter
« Reply #3 on: August 25, 2011, 04:13:06 PM »
Here is my solution:

Code: [Select]
;; GetVisibilityParameterName  -  Lee Mac
;; Returns the name of the Visibility Parameter of a Dynamic Block (if present)
;; Arguments: VLA Block Reference Object

(defun LM:GetVisibilityParameterName ( block / visib ) 
    (if
        (and
            (vlax-property-available-p block 'effectivename)
            (setq block
                (vla-item
                    (vla-get-blocks (vla-get-document block))
                    (vla-get-effectivename block)
                )
            )
            (eq :vlax-true (vla-get-isdynamicblock block))
            (eq :vlax-true (vla-get-hasextensiondictionary block))
            (setq visib
                (vl-some
                    (function
                        (lambda ( pair )
                            (if
                                (and
                                    (= 360 (car pair))
                                    (eq "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr pair)))))
                                )
                                (cdr pair)
                            )
                        )
                    )
                    (dictsearch
                        (vlax-vla-object->ename (vla-getextensiondictionary block))
                        "ACAD_ENHANCEDBLOCK"
                    )
                )
            )
        )
        (cdr (assoc 301 (entget visib)))
    )
)

The above requires a VLA (Dynamic) Block Reference Object and will return the name of the Visibility Parameter associated with that object (if present).

With knowledge of the Visibility Parameter name, one can retrieve the correct Dynamic Property object and hence the Visibility State:

Code: [Select]
;; GetVisibilityState  -  Lee Mac
;; Returns the value of the Visibility Parameter of a Dynamic Block (if present)
;; Arguments: VLA Block Reference Object

(defun LM:GetVisibilityState ( block )
    (
        (lambda ( name )
            (vl-some
                (function
                    (lambda ( prop )
                        (if (eq name (vla-get-propertyname prop))
                            (vlax-get prop 'value)
                        )
                    )
                )
                (vlax-invoke block 'getdynamicblockproperties)
            )
        )
        (LM:GetVisibilityParameterName block)
    )
)