Sendo este o primeiro artigo técnico do blog autolisp, vou começar por resolver um problema bem comum para os desenvolvedores da linguagem: o acesso à informações de atributos de blocos em desenhos do Autocad. Vejam o Exemplo:
As informações doa atributos das tags "HI" e "LW" do bloco "nivel" são visíveis no desenho. Mas e para manipular as mesmas numa rotina autolisp? Primeiro vamos a explicação complicada... Todo bloco do autocad tem um entity-name, que por sua vez possue uma entity-list com todas as informações do bloco, como escala, layer, coordenada, etc. Os atributos estão definidos ainda em outra lista (entity-data). No exemplo ilustrado esta lista possuí 2 valores.
Então, o roteiro para acessar um atributo de um bloco é o seguinte: 1) selecionar o bloco; 2) descobrir o entity-name deste bloco; 3) Percorrer a lista de atributos um a um, até situar o ponteiro na posição da lista onde se encontra a informação desejada. Para isso, usa-se a função nativa entnext. Vejamos o exemplo para se carregar na variável "ATRIBUTO" a informação contida no "attribute LW" do bloco "nivel.dwg":
...
(setq BLOCO (ssget)) ;seleciona-se pelo mouse o bloco "nivel" na variável BLOCO
(setq ENT-NOME (ssname BLOCO 0)) ;descobre o entity-name
(setq ENT-ELE ENT-NOME) ;passa-se o entity-name a uma variável de carga
(setq ENT-ELE (entnext ENT-ELE)) ;carrega-se o 1º atrib da lista ("HI")
(setq ENT-ELE (entnext ENT-ELE)) ;carrega-se o 2º atrib da lista ("LW")
(setq VALOR_ATTRIB (cdr (assoc 1 (entget ENT-ELE)))) ;extraí-se o valor do atributo do par associado da entyty-data
(princ VALOR_ATTRIB) ;plotagem da variável carregada com o atributo
;>11 -> valor apresentado no prompt do autocad
...
Agora, imaginem um bloco com 100 atributos, como os de uma legenda de uma planta de obra civil? Para facilitar a vida de todos, disponibilizo aqui a função "retorna_attrib". Na mesma você passa o entity-name do bloco e a posição do atributo a ser consultado, e o valor deste será retornado. A chamada da função é assim:
(retorna_attrib [entity-name] [ posição do atributo desejado]), sendo:
[entity-name]: do bloco desejado;
[ posição do atributo desejado]: em que posição está o atributo desejado.
Abaixo o código da mesma para uso:
; RETORNA ATRIBUTO (função pré-elaborada)
(defun retorna_attrib (BLOCO_AUX NUM_ATTRIB)
(setq VALOR_ATTRIB nil)
(setq EL BLOCO_AUX)
(setq CONTADOR 1)
(while (<= CONTADOR NUM_ATTRIB)
(setq EL (entnext EL))
(setq CONTADOR (1+ CONTADOR))
)
(setq VALOR_ATTRIB (cdr (assoc 1 (entget EL))))
VALOR_ATTRIB
)
É só copiar acima da rotina principal, e chamá-la então. Nosso exemplo ficaria assim:
(defun c:principal ()
(setq BLOCO (ssget)) ;seleciona-se pelo mouse o bloco "nivel" na variável BLOCO
(setq VALOR_ATTRIB (retorna_attrib BLOCO 2)
(princ VALOR_ATTRIB) ;plotagem da variável carregada com o atributo
)
;>11 -> valor apresentado no prompt do autocad
Boa Noite
e qualquer dúvida estou a disposição.
Lucas