Как вставить блок с пользовательскими свойствами с помощью AutoLISP? - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь вставить блоки с пользовательскими свойствами. Как мне установить эти переменные?

Внутри блока «Лиственные» есть пользовательское свойство, называемое «видимость», с различными стилями (Видимость 1, Видимость 2, Видимость 3, ...).

Например, как бы я вставил блок Deciduous с Visibility 3.

(DEFUN C:TREE ( / DECIDUOUS CONIFER SHRUBMEDIUM SHRUBSMALL)
  (INITGET 1 "DECIDUOUS CONIFER SHRUBMEDIUM SHRUBSMALL")
  (OR
    (SETQ RETKWORD (GETKWORD "\nSpecify tree type: [DECIDUOUS/CONIFER/SHRUBMEDIUM/SHRUBSMALL]:"))
    (SETQ RETKWORD "DECIDUOUS")
    )
  (IF (= RETKWORD "DECIDUOUS")
    (PROGN
      (SETQ OLDLAYER (GETVAR "CLAYER"))
      (SETQ FLAG (TBLSEARCH "LAYER" "L-PLNT-DECD"))
      (IF FLAG
    (SETVAR "CLAYER" "L-PLNT-DECD")
    )
      (INITGET 1 "Visibility1 Visibility2 Visibility3")
      (OR
    (SETQ CMDKWORD (GETKWORD "\nPick a command: [Visibility1/Visibility2/Visibility3]:"))
    )
      (IF (= CMDKWORD "Visibility3")
    (PROGN
      (COMMAND "INSERT"
           "TT-L-TREE-DECIDUOUS"
           )
      )
    )
      (PRINC)
      )
    )
  )

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Ответ на этот вопрос в конечном итоге зависит от того, требуется ли вам визуальный предварительный просмотр вставленной ссылки на блок, предоставленный командой AutoCAD INSERT.

Поскольку стандартная команда AutoCAD INSERT не запрашивает значения параметров динамического блока во время вставки блока, вам нужно будет вставить блок и затем управлять состоянием видимости, используя свойства и методы ActiveX вставленной ссылки на динамический блок, в частности, с использованием метода getdynamicblockproperties.


Если визуальный предварительный просмотр вставленного блока НЕ ​​требуется ...

... тогда вы можете полностью отказаться от команды INSERT и использовать метод insertblock целевого объекта-контейнера (определение модели пространства / paperpace / блока), который будет возвращать ссылку на блок VLA-объект.

Вот базовый пример, демонстрирующий, как использовать метод insertblock:

(defun c:test ( / dwg ins )
    (if
        (and
            (setq dwg (getfiled "Select Block" "" "dwg" 16))
            (setq ins (getpoint "\nSpecify insertion point: "))
        )
        (vla-insertblock
            (vlax-get-property
                (vla-get-activedocument (vlax-get-acad-object))
                (if (= 1 (getvar 'cvport))
                    'paperspace
                    'modelspace
                )
            )
            (vlax-3D-point (trans ins 1 0))
            dwg
            1.0 1.0 1.0 0.0
        )
    )
    (princ)
)
(vl-load-com) (princ)

Этот метод возвращает ссылочный vla-объект блока, чьи свойства динамического блока вы можете затем использовать, используя массив свойств динамического блока, возвращаемых методом getdynamicblockproperties.

Поскольку вы хотите, в частности, изменить состояние видимости, вы можете рассмотреть следующий набор функций, который я разработал как часть моей библиотеки динамических блоков , чтобы изменить состояние видимости поставляемого ссылочный объект блока:

;; Set Dynamic Block Visibility State  -  Lee Mac
;; Sets the Visibility Parameter of a Dynamic Block (if present) to a specific value (if allowed)
;; blk - [vla] VLA Dynamic Block Reference object
;; val - [str] Visibility State Parameter value
;; Returns: [str] New value of Visibility Parameter, else nil

(defun LM:SetVisibilityState ( blk val / vis )
    (if
        (and
            (setq vis (LM:getvisibilityparametername blk))
            (member (strcase val) (mapcar 'strcase (LM:getdynpropallowedvalues blk vis)))
        )
        (LM:setdynpropvalue blk vis val)
    )
)

;; Get Visibility Parameter Name  -  Lee Mac
;; Returns the name of the Visibility Parameter of a Dynamic Block (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; Returns: [str] Name of Visibility Parameter, else nil

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

;; Get Dynamic Block Property Allowed Values  -  Lee Mac
;; Returns the allowed values for a specific Dynamic Block property.
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; Returns: [lst] List of allowed values for property, else nil if no restrictions

(defun LM:getdynpropallowedvalues ( blk prp )
    (setq prp (strcase prp))
    (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'allowedvalues)))
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

;; Set Dynamic Block Property Value  -  Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil

(defun LM:setdynpropvalue ( blk prp val )
    (setq prp (strcase prp))
    (vl-some
       '(lambda ( x )
            (if (= prp (strcase (vla-get-propertyname x)))
                (progn
                    (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
                    (cond (val) (t))
                )
            )
        )
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

Вы могли бы вызвать вышеупомянутые функции из предыдущего примера, который я представил, следующим образом (конечно, изменив имя состояния видимости в соответствии с вашим блоком):

(defun c:test ( / dwg ins )
    (if
        (and
            (setq dwg (getfiled "Select Block" "" "dwg" 16))
            (setq ins (getpoint "\nSpecify insertion point: "))
        )
        (LM:SetVisibilityState
            (vla-insertblock
                (vlax-get-property
                    (vla-get-activedocument (vlax-get-acad-object))
                    (if (= 1 (getvar 'cvport))
                        'paperspace
                        'modelspace
                    )
                )
                (vlax-3D-point (trans ins 1 0))
                dwg
                1.0 1.0 1.0 0.0
            )
            "YourVisibilityState"
        )
    )
    (princ)
)
(vl-load-com) (princ)

Если требуется визуальный предварительный просмотр вставленного блока ...

... Затем, кроме использования собственной версии стандартной команды INSERT с использованием цикла grread (который также должен имитировать все вспомогательные средства для рисования, такие как Object Snap и Orthomode ), вам нужно использовать команду INSERT.

Однако, поскольку состояние видимости блока можно изменить только после вставки ссылки на блок, визуальный предварительный просмотр, отображаемый для пользователя, будет неточным.

Чтобы получить лучшее из обоих миров, я ранее предложил следующее возможное решение (наряду с сопровождающей функцией, размещенной здесь ):

;; Example demonstrating a method to insert a Dynamic Block with a Visibility State already set.
;; Lee Mac  -  2013-12-24

(defun c:test ( / *error* att blk def doc ent new obj par spc tmp vis )

    (defun *error* ( msg )
        (if (= 'int (type att))
            (setvar 'attreq att)
        )
        (foreach obj (list new def)
            (if (and (= 'vla-object (type obj)) (not (vlax-erased-p obj)))
                (vl-catch-all-apply 'vla-delete (list obj))
            )
        )
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (cond
        (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer))))))
            (princ "\nCurrent layer locked.")
        )
        (   (null (setq blk (getfiled "Select Dynamic Block with Visibility States" "" "dwg" 16)))
            (princ "\n*Cancel*")
        )
        (   (progn
                (setq doc (vla-get-activedocument (vlax-get-acad-object))
                      spc (vlax-get-property doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
                      obj (vlax-invoke spc 'insertblock '(0.0 0.0 0.0) blk 1.0 1.0 1.0 0.0)
                )
                (vla-put-visible obj :vlax-false)
                (= :vlax-false (vla-get-isdynamicblock obj))
            )
            (princ "\nSelected block is not dynamic.")
            (vla-delete obj)
        )
        (   (null (setq par (LM:getvisibilityparametername obj)))
            (princ "\nSelected block does not have a visibility parameter.")
            (vla-delete obj)
        )
        (   (null (setq vis (car (LM:listbox "Choose a Visibility State" (acad_strlsort (LM:getdynpropallowedvalues obj par)) 0))))
            (princ "\n*Cancel*")
            (vla-delete obj)
        )
        (   t
            (LM:setdynpropvalue obj par vis)
            (setq tmp 0)
            (while (tblsearch "block" (setq blk (strcat "tmp" (itoa (setq tmp (1+ tmp)))))))
            (vla-put-visible
                (car
                    (vlax-invoke doc
                        'copyobjects
                        (list obj)
                        (setq def (vlax-invoke (vla-get-blocks doc) 'add '(0.0 0.0 0.0) blk))
                    )
                )
                :vlax-true
            )
            (vla-delete obj)
            (setq ent (entlast)
                  att (getvar 'attreq)
            )
            (setvar 'attreq 0)
            (if
                (and
                    (vl-cmdf "_.-insert" blk "_S" 1.0 "_R" 0.0 "\\")
                    (not (eq ent (setq ent (entlast))))
                    (= "AcDbBlockReference" (vla-get-objectname (setq new (vlax-ename->vla-object ent))))
                )
                (progn
                    (vla-explode new)
                    (vla-delete  new)
                )
            )
            (vl-catch-all-apply 'vla-delete (list def))
        )
    )
    (princ)
)

;; Get Visibility Parameter Name  -  Lee Mac
;; Returns the name of the Visibility Parameter of a Dynamic Block (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; Returns: [str] Name of Visibility Parameter, else nil

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

;; Get Dynamic Block Property Allowed Values  -  Lee Mac
;; Returns the allowed values for a specific Dynamic Block property.
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; Returns: [lst] List of allowed values for property, else nil if no restrictions

(defun LM:getdynpropallowedvalues ( blk prp )
    (setq prp (strcase prp))
    (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'allowedvalues)))
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

;; Set Dynamic Block Property Value  -  Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil

(defun LM:setdynpropvalue ( blk prp val )
    (setq prp (strcase prp))
    (vl-some
       '(lambda ( x )
            (if (= prp (strcase (vla-get-propertyname x)))
                (progn
                    (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
                    (cond (val) (t))
                )
            )
        )
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

;; List Box  -  Lee Mac
;; Displays a DCL list box allowing the user to make a selection from the supplied data.
;; msg - [str] Dialog label
;; lst - [lst] List of strings to display
;; bit - [int] 1=allow multiple; 2=return indexes
;; Returns: [lst] List of selected items/indexes, else nil

(defun LM:listbox ( msg lst bit / dch des tmp rtn )
    (cond
        (   (not
                (and
                    (setq tmp (vl-filename-mktemp nil nil ".dcl"))
                    (setq des (open tmp "w"))
                    (write-line
                        (strcat "listbox:dialog{label=\"" msg "\";spacer;:list_box{key=\"list\";multiple_select="
                            (if (= 1 (logand 1 bit)) "true" "false") ";width=50;height=15;}spacer;ok_cancel;}"
                        )
                        des
                    )
                    (not (close des))
                    (< 0 (setq dch (load_dialog tmp)))
                    (new_dialog "listbox" dch)
                )
            )
            (prompt "\nError Loading List Box Dialog.")
        )
        (   t     
            (start_list "list")
            (foreach itm lst (add_list itm))
            (end_list)
            (setq rtn (set_tile "list" "0"))
            (action_tile "list" "(setq rtn $value)")
            (setq rtn
                (if (= 1 (start_dialog))
                    (if (= 2 (logand 2 bit))
                        (read (strcat "(" rtn ")"))
                        (mapcar '(lambda ( x ) (nth x lst)) (read (strcat "(" rtn ")")))
                    )
                )
            )
        )
    )
    (if (< 0 dch)
        (unload_dialog dch)
    )
    (if (and tmp (setq tmp (findfile tmp)))
        (vl-file-delete tmp)
    )
    rtn
)
(vl-load-com) (princ)

Мое решение по существу включает временную вставку ссылки на блок, соответствующую настройку состояния видимости, создание определения временного блока, содержащего настроенный динамический блок, а затем использование визуального предварительного просмотра, предлагаемого стандартной командой INSERT, для вставки ссылки на временный блок , который затем взорван и очищен от чертежа.

1 голос
/ 02 мая 2019

Блоки с пользовательскими свойствами называются динамическими блоками. Детали и образцы Вы можете найти здесь

p.s. Спасибо @ LeeMac

...