37
Aula 1/7 - Programando em Autolisp Introdução por R.C. Ruschel, DCC-FEC-UNICAMP, Agosto 1997 Interfaces do AutoCAD: Além da interação pela linha de comando e por menus o AutoCAD R13 permite: executar um conjunto de comandos por meio de command-scripting a programação pelo usuário utilizando-se: a linguagem de programação AutoLISP ou a linguagem C através do ADS (AutoCAD Developing System) A forma de programação depende: das necessidades da aplicação (desempenho, custo) da experiência de programação da equipe envolvida AutoLisp: O AutoLisp é baseado na linguagem de programação LISP (List Processing) de aprendizado simples porém poderosa. O AutoCAD tem um interpretador de Lisp embutido, permitindo a digitação de expressões/funções AutoLisp na linha de comando e sua interpretação automática. O AutoCAD inclue rotinas AutoLisp bastante úteis nos sub-diretórios sample e support. Aplicações em AutoLisp: São armazenadas em arquivos ASCII com extensão .lsp. Devem ser carregadas para o ambiente do AutoCAD para serem executadas. Como carregar: na linha de comando pelo menu Tools/Applications ... de forma automática incluíndo-a no arquivo acad.lsp ADS - AutoCAD Developing System: Ambiente de programação baseado na linguagem C. Aplicações desenvolvidas no ADS se comunicam com o AutoCAD via AutoLisp. Todas funções básicas em ADS fazem uma chamada para uma função equivalente em AutoLisp. ADS x AutoLisp: A escolha ADS x AutoLisp depende: da experência do programador

90784248-Curso-de-Lisp

Embed Size (px)

Citation preview

Page 1: 90784248-Curso-de-Lisp

Aula 1/7 - Programando em Autolisp

Introdução

por R.C. Ruschel, DCC-FEC-UNICAMP, Agosto 1997

Interfaces do AutoCAD:

•Além da interação pela linha de comando e por menus o AutoCAD R13 permite:•executar um conjunto de comandos por meio de command-scripting•a programação pelo usuário utilizando-se:

•a linguagem de programação AutoLISP ou•a linguagem C através do ADS (AutoCAD Developing System)

•A forma de programação depende:•das necessidades da aplicação (desempenho, custo)•da experiência de programação da equipe envolvida

AutoLisp:

•O AutoLisp é baseado na linguagem de programação LISP (List Processing)•de aprendizado simples porém poderosa.

•O AutoCAD tem um interpretador de Lisp embutido, permitindo a digitação de expressões/funções AutoLisp na linha de comando e sua interpretação automática.•O AutoCAD inclue rotinas AutoLisp bastante úteis nos sub-diretórios sample e support.

Aplicações em AutoLisp:

•São armazenadas em arquivos ASCII com extensão .lsp.•Devem ser carregadas para o ambiente do AutoCAD para serem executadas.•Como carregar:

•na linha de comando•pelo menu Tools/Applications ...•de forma automática incluíndo-a no arquivo acad.lsp

ADS - AutoCAD Developing System:

•Ambiente de programação baseado na linguagem C.•Aplicações desenvolvidas no ADS se comunicam com o AutoCAD via AutoLisp.

•Todas funções básicas em ADS fazem uma chamada para uma função equivalente em AutoLisp.

ADS x AutoLisp:

•A escolha ADS x AutoLisp depende:•da experência do programador

Page 2: 90784248-Curso-de-Lisp

•do desempenho desejado para a aplicação•aplicações em ADS são + rápidas e utilizam menos memória

•do desempenho do processo de desenvolvimento da applicação•AutoLisp é recomendado para prototipagem e aplicações onde o custo do desenvolvimento e manutenção é mais importante que o desempenho da aplicação.

•da portabilidade desejada para a aplicação•Aplicações em AutoLisp são mais portáteis. Dependem apenas do AutoCAD para a plataforma desejada.•Aplicações em ADS dependem do AutoCAD, da versão da linguagem C e do ambiente de desenvolvimento.

Lisp:

•A LP Lisp é:•da mesma época que o Fortran•diferente de outras LPs, i.e., dados e programas são tratados da mesma forma (tudo como listas) e são colodados no mesmo espaço de memória do computador.•interpretada, i.e.,toda vez que o programa é executado o código fonte é avaliado.•muito utilizada na programação da área de inteligência artificial.

Lisp utiliza a notação infixa (operador seguido dos operandos):

1 + 2 ----------> (+ 1 2)

Listas - composição:

•inicia com "(", termina com ")" e é composta por átomos, que podem ser:•um número interio: -32.768 a 32.767•um número real: -4.932 a 4.932 onde e: -307 a 307•uma cadeia de caracteres (string): "Ola", "Insira um ponto:"•um símbolo: nome de função interna ou definida pelo usuário•uma variável: um símbolo que representa um nome de dado•um nil: valor nulo (vazio)•um ponteiro para arquivo (file descriptor): nome de arquivo•uma sub-rotina (subr): nome de funções internas e externas do AutoLisp•um nome de entidade: código numérico associado ao objeto numa sessão de trabalho•conjunto de seleção: conjunto de objetos selecionados

Listas - Exemplos:

Lista de dados:

(2.0 3.5 7.6)("paola" (11 06 1996) 3.150 51)

Lista de programa (primeiro elemento é um nome de função ou uma subr):

(setq A 21) ;setq é uma subr, A é um símbolo (nome de variável)

(list 2 3 4) ;list é uma subr

Page 3: 90784248-Curso-de-Lisp

(defun vistalatdir ()(command "vpoint" "1,0,0")) ; defun e command são subrs

(vistalatdir) ;vistalatdir é um símbolo (nome de função)

Avaliando expressões em Lisp:

•O interpretador do Lisp é denominado avaliador.•Toda a entrada para o Lisp é processada por meio do avaliador.•Tudo dentro do AutoLisp em relação ao avaliador retorna um valor como resultado, i.e.:

•qdo um elemento de dado é apresentado ao avaliador, o valor atribuido ao elemento é retornado.•qdo um símbolo é apresentado, o valor da ligação atual do símbolo é retornado.•qdo uma lista de programa, é apresentada, essa é executada e o valor final da execução é retornado.

Avaliando Listas de programa:

•Se o primeiro elemento da lista for o nome de uma subr ou uma função definida, a subr ou função é executada; o restante da lista é usado como parâmetros para a função ou subr.•Se o primeiro elemento da lista não for uma função ou subr, obtém-se uma mensagem de erro: "bad function" (função ruim).

Exemplos de avaliação de listas de programa:(list 1 2 3) ;constrói uma lista de 3 números inteiros ;retorna (1 2 3)(2.0 3.0 6.6) ;retorna erro:bad function(setq a 1.0) ;retorna o valor 1.0 atribuído a variável a(set 'a 1.0) ;idem mas usando o símbolo '(set (quote a) 1.0);idem mas usando a subr quote

Obs: a subr quote é empregada para acessar o nome da referência (não o valor) de um símbolo. Portanto, o 2o. exemplo para ser processado como um lista de programa deveria ser:

(quote (2.0 3.0 6.6)) ou '(2.0 3.0 6.6)

AutoLisp na linha de comando do AutoCAD:

•É possível avaliar expressões em AutoLisp e até funções na linha de comando do AutoCAD.•Este recurso é muito utilizado para experimentação e testes.•Basta digitar na linha de comando a expressão ou função desejada, e.g.:

Command: (setq A 2.0)2.0Command: (setq B 3.0)3.0Command: (setq C (+ A B))5.0Command: !C5.0Command: (setq p1 (list 1 2))(1 2)Command: (setq p2 (list 10 20))(10 20)

Page 4: 90784248-Curso-de-Lisp

Command: (command "line" p1 p2 "")line From point:to point:to point:Command: nilCommand:(defun vistalatdir ()(command "vpoint" "1,0,0"))VISTALATDIRCommand:(vistalatdir)

Desenvolvendo programas em AutoLisp - sem um ambiente de programação:

•Utiliza-se simultaneamente dois programas o AutoCAD e um editor de texto simples (e.g. Edit ou NotePad do Windows).

•Entra-se no AutoCAD•Chama-se o editor de texto utilizando o comando EDIT•Edita-se as funções que compõem o programa num arquivo com extensão LSP (e.g. programa1.lsp). Salva edição e sai do editor (automaticamente retornando para o AutoCAD).•Carrega-se o arquivo no AutoCAD.•Executa-se funções contidas no arquivo com (nome-da-função) ou nome-da-função

Arquivo acad.pgp:

•Para fazer com que o comando EDIT chame o editor de texto diferente do edit do windows é necessário alterar uma linha do arquivo r13\com\support\acad.pgp:

Linha original:EDIT,EDIT,0, File to edit: ,4

Nova linha:EDIT,c:\windows\notepad, 0, File to edit: ,4

•O subdiretório onde o notepad.exe está localizado pode variar. Portanto, verifique no seu microcomputador o subdiretório correto.•A mesma observação vale para a localização do arquivo acad.pgp.

Carregando programas AutoLisp no AutoCAD:

•Na linha de comando digitar (load "unidade-de-disco:\\sub-diretório\\nome-do-promaga-com-extensão"), e.g.:

Command: (load "c:\\trab\\programa1.lsp")

•No pull-down menu Tools/Applications indicar arquivo a ser carregado procurando sua localização com auxílio do botton File e depois carrega-lo acionando Load.

Exemplo - isomets.lsp:

•Conteúdo do arquivo isomets.lsp:

;;;Vista isometrica lat-dir, fundo, por-cima(defun c:iso1() (command "vpoint" "1,1,1"));;;Vista isometrica lat-esq, fundo, por-cima(defun c:iso2() (command "vpoint" "-1,1,1"))

Page 5: 90784248-Curso-de-Lisp

;;;Vista isometrica lat-dir, frente, por-cima(defun c:iso3() (command "vpoint" "1,-1,1"))

•Carregando o arquivo isomets.lsp e executando funções:

Command: (load "c:\\trab\\isomets.lsp")ISO3Command: iso1vpoint Rotate/ <0.0000 0.0000 1.0000>: 1,1,1 Regenerating drawingCommand: nil

Exemplo - media.lsp:

•Conteúdo do arquivo media.lsp

;;;Programa principal(defun c:mediatestes() (setq t1(getreal "\nNota teste-1: ")) (setq t2(getreal "\nNota teste-2: ")) (setq nota (soma-e-divide)) (princ "\nMedia dos testes = ") (princ nota) (princ));;;funcao soma-e-divide(defun soma-e-divide() (/ (+ t1 t2) 3.0))

•Carregando o arquivo media.lsp e executando função mediatestes:

Command: (load "c:\\trab\\media.lsp")SOMA-E-DIVIDECommand: mediatestesNota teste-1: 5.0Nota teste-2: 7.0Media dos testes = 6.0Command:

Homework:

•Ler o capítulo 1 de (Gaál, 1997) ou capítulos 1 e 2 de (Kramer&Kramer, 1995).

•Faça os seguintes exercícios propostos por (Gaál, 1997):1.Crie uma rotina que aplique um offset de 3 unidades numa entidade e altere em seguida o layer ao qual ela pertence para OFFLINES. Suponha que o layer já exista.

2.Crie um bloco qualquer (interno ao desenho). A seguir, crie uma rotina que insira este bloco rapidamente, com as escala x e y constantes e rotação 0, explodindo-o em seguida. O usuário deverá somente informar a posição em que será inserido o bloco.

Page 6: 90784248-Curso-de-Lisp

Aula 2/7 - Programando em AutoLISP

Cálculos, Variáveis e Listas

Profa. Regina C. Ruschel,DCC-FEC-UNICAMP,Campinas, Julho 1997

Cálculos:

•Expressões matemáticas são escritas na notação infixa, i.e., operador antecede operandos:•1+2 (+ 1 2)•32.12 - 22.5 (- 32.12 22.5)•1 + 2 + 3 + 4 (+ 1 2 3 4)•7 * (9 / 2) (* 7 (/ 9 2))

Variáveis:

•A variável é um recurso utilizado pelo programa para executar funções iguais mas com valores que podem ser alterados a cada execução.•Existem três tipos:

•livre (global)•associada•local

•O tipo da variável é determinado pela sua posição na lista de parâmetros na definição da função.

Variáveis - tipos (esquema):(defun func1 (A B / C D) ; A,B: variáveis assocs, C,D: variáveis locais ... (setq X ...) ; X variável livre ...)(defun func2 () (setq Y (+ X 2) ...)

Variáveis - tipos (definições):

Variável livre:Equivalente a variáveis globais. São utilizadas por mais de uma função. Não deve fazer parte da lista de parâmetros na definição da função, pois não pertence a nenhuma função específica e sim a qualquer uma.

Variável local:Equivalente a uma variável temporária. Utilizada para armazenar dados auxiliares dentro de uma determinada função.

Page 7: 90784248-Curso-de-Lisp

Variável associada:Equivalente a parâmetros de entrada de uma função.

Variáveis associadas e locais são zeradas na saída da função.

Exemplo - função com variáveis locais:;;;Cálculo da circunferência a partir do ;;;diâmetro inserido pelo usuário(defun c:circun(/ DIA CIR) (setq DIA (getreal "\nDigite o valor de um diâmetro: ")) ;pi é uma constante do sistema (setq CIR (* DIA pi)) (princ "\nDiametro = ") (princ DIA) (princ "\nCircunferencia = ") (princ CIR) ;este princ faz com que a função não retorne um nil (princ))

Exemplo - função com variável associada:

•arquivo progcir.lsp:

(defun circun(DIA) (setq CIR (* DIA pi)) (princ "\nDiametro = ") (princ DIA) (princ " ") (princ "Circunferencia = ") (princ CIR) (princ))

•linha de comando do AutoCAD:

Command: (load "progcir.lsp")CIRCUNCommand: (circun 34)Diametro = 34 Circunferencia = 106.814Command:

Exemplo - função com variáveis livres:

•Conteúdo do arquivo média.lsp

;;;Programa principal(defun c:mediatestes() (setq t1(getreal "\nNota teste-1: ")) (setq t2(getreal "\nNota teste-2: ")) (setq nota (soma-e-divide)) (princ "\nMedia dos testes = ") (princ nota) (princ));;;funcao soma-e-divide(defun soma-e-divide() (/ (+ t1 t2) 3.0))

•Carregando o arquivo e executando a função mediatestes

Command: (load "c:\\trab\\media.lsp")SOMA-E-DIVIDECommand: mediatestes

Page 8: 90784248-Curso-de-Lisp

Nota teste-1: 5.0Nota teste-2: 7.0Media dos testes = 6.0Command:

Manipulação de listas de dados:

•Dados agrupados em listas são manipulados por funções específicas.•Existe apenas funções para obter

•o primeiro átomo da lista - função car•o resto da lista (todos elementos exceto o primeiro) - função cdr

•Para obter o 2o., 3o. átomo da lista utiliza-se funções derivadas a partir de concatenações (máximo de 4) de car e cdr:

•cadr - retorna o 1o. átomo do resto da lista original. Portanto, retorna o 2o. átomo da lista original.•cdaddr = cdr + cdr + car + cdr

•Para ler uma subr derivada de concatenações de cars e cdrs:•leia de trás para frente,•despreze a primeira e última letra,•um d representa um cdr e um a representa um car.

Comando car, cdr e derivados:Command: (setq TESTE(list 10 20 30 40))(10 20 30 40))Command: !TESTE(10 20 30 40)Command: (car TESTE) ;retorna o primeiro átomo da lista10Command: (cdr TESTE) ;retorna uma lista sem o primeiro átomo da lista original(20 30 40)Command: cadr TESTE) ;executa um cdr sobre a lista original e um car sobre o resultado20Command: (caddr TESTE) ;executa um cdr sobre a lista original, ;+ 1 cdr e finalmente um car sobre os respectivos resultados30

Exercício - manipulação de lista de dados:

•Na linha de commando do AutoCAD:•Construa a lista ((11 22) (33 44) (55 66))•Obtenha o número 22 da lista•Obtenha a lista (55 66)

Exercício - desenvolver função para desenhar círculo com linha de centro:Dia : diâmetro do círculoCen : centro do círculoPT1, PT2 : quadrantes horizontaisPT3, PT4 : quadrantes verticais

Page 9: 90784248-Curso-de-Lisp

As linha de centro devem ser colocadas no Layer LC pré-existente com tipo de linha hidden.

Exercício - função que desenha círculo com linha de centro:(defun c:cc (/ CEN DIA IN PT1 PT1X PT1Y PT2 PT2X PT2Y PT3 PT3X PT3Y PT4 PT4X PTY4 LAY) (initget 7) (setq CEN (getpoint "\nCentro do Circulo : ")) (initget 7) (setq DIA (getreal "\nDiametro : ")) (command "circle" CEN "d" DIA);construcao dos pontos das linhas de centro (setq IN (* DIA 1.1)) ; valor do incremento (setq PT1X (- (car CEN) IN)) (setq PT1Y (cadr CEN)) (setq PT1 (list PT1X PT1Y)) (setq PT2X (+ (car CEN) IN)) (setq PT2 (list PT2X PT1Y)) (setq PT3X ) (setq PT3Y ) (setq PT3 ) (setq PT4Y ) (setq PT4 );desenho das linhas de centro (setq LAY (getvar "clayer")) (command "layer" "set" "lc" "" "line" PT1 PT2 "" "line" PT3 PT4 "") (setvar "clayer" LAY) (princ))

Page 10: 90784248-Curso-de-Lisp

Aula 3/7 - Programando em AutoLISP

Controle de fluxo. Get???s e Prin?s.

por R. C. Ruschel, DCC-FEC-UNICAMP, Agosto 1997

Função condicional - if:

Figura A: If A<0 executa a função prog1.

(if (< A 0) (prog1))

Figura B: If A<0 executa as funções prog1 e prog2.

(if (< A 0) (progn (prog1) (prog2) ))

Figura C: If A<0 executa a função prog1, senão executa a função prog2.

(if (< A 0) (prog1) (prog2))

Figura D: If A<0 executa as funções prog1 e prog2, senão executa as funções prog3 e prog4.

(if (< A 0) (progn (prog1) (prog2) ) (progn (prog3)

Page 11: 90784248-Curso-de-Lisp

(prog4) ))

Função condicional - cond:

•Ifs sequenciais com condicionais de igualdade são melhor codificados pelo comando cond.

Figura E: If A=1 executa a função prog1, senão se A=2 executa a função prog2, senão executa a função prog3.

;; primeira opção - ifs encadeados(if (= A 1) (prog1) (if (= A 2) (prog2) (prog3) ))

;; segunda opção - ifs sequenciais(if (= A 1) (prog1))(if (= A 2) (prog2))(if (= A 3) (prog3))

Figura F: Caso A=1 execute a função prog1, A=2 execute a função prog2, A=3 execute a função prog3.

(cond (= A 1)(prog1) (= A 2)(prog2) (= A 3)(prog3))

Operadores de comparação:

= (igual)(if (= A B C) (rotina))

/= (diferente)(if (/= A B) (rotina))

< (menor)(if (< A B) (rotina))

<= (menor ou igual)(if (<= A B) (rotina))

> (maior)(if (> A B) (rotina))

Page 12: 90784248-Curso-de-Lisp

>= (maior ou igual)(if (>= A B) (rotina))

eq (idêntico)(if (eq A B) (rotina))

equal (resultar em =)(if (equal A B) (rotina)

Diferença entre =, eq e equal:

•(= A B ) retorna verdadeiro se argumentos forem iguais.•(eq A B) retorna verdadeiro se argumentos derivados um do outro, e.g.:

(setq f1 '(a b c)) (setq f2 '(a b c)) (setq f3 f2)(eq f3 f2) ;retorna T (true) pois f3 é derivado de f1(eq f1 f3) ;retorna nil pois f3 não é derivado de f1(= f1 f2) ;retorna nil

•(equal A B) retorna verdadeiro se argumentos resultarem em valores iguais, e.g.:

(equal f1 f2)(eq f1 f3) ;retornam T

Funções de repetição - while e repeat:

•Utilizar while quando se deseja executar um conjunto de expressões enquanto uma condição for satisfeita.•Utilizar repeat quando se deseja executar um conjunto de expressões N vezes.

Figura G: Enquanto RESP=S execute a função prog1.

(setq RESP "S")(while (= RESP "S") (prog1) (initget "S N") (prompt "\nDeseja continuar? (S/N) ") (setq RESP (getkword)))

Figura H: Repita Num vezes a funções prog1 e prog2.

(setq NUM 10)(repeat NUM (prog1) (prog2))

Exemplo - função com if e while:;;;abertura condicionada de arquivo(defun c:cc (/ CODIGO FOLHA NOME ARQ) (initget "A0 A1 A2 A3 A4") (prompt "\nQual o formato da folha? ") (setq FOLHA (getkword "Folha [A0, A1, A2, A3 ou A4]: ")

Page 13: 90784248-Curso-de-Lisp

(setq CODIGO " ") (while (/= (strlen CODIGO) 6) (prompt "\nO codigo do desenho deve ter apenas 6 digitos. ") (setq CODIGO (getstring "Insira o codigo: ")) ) (setq NOME (strcat "c:\\" FOLHA "\\" CODIGO ".DWG")) (setq ARQ (findfile NOME)) (if (/= ARQ nil) (command "OPEN" ARQ) (alert (strcat "O arquivo " (strcase NOME) "\nnao foi encontrado.")) ))

Obtendo dados:

•As rotinas escritas em AutoLisp podem interagir com o usuário e o sistemas. Portanto, são necessárias funções para obter informação:

•getangle, getcorner, getdist, getenv, getfiled, getint, getkword, getorient, getpoint, getreal, getstring, getvar

•Na interação com o usuário deve-se utilizar prompts (mensagens com pedido de inserção de dados) claros e realizar testes de consistência sobre os dados obtidos.

•A função initget restringe dados de entrada.

Funções getreal, getint e getstring:

getreal(setq NUM (getreal "Digite a escala: "))

getint(setq QTD (getint "Digite numero de itens: "))

getstring(setq ARQ (getstring "Digite nome do arquivo: ")) ;texto sem espaços(setq TIT T(getstring T "Insira titulo do projeto: ")) ;texto com espaços

Funções getpoint, getcorner e getdist:

getpoint(setq PT1 (getpoint "Clique no primeiro ponto: "))(setq PT2 (getpoint PT1 "\nClique no segundo ponto: ")); com fita elástica

getcorner(setq PONTO1 (getpoint "Clique no primeiro canto: "))(setq PONTO2 (getcorner PONTO1 "Outro canto: "))

Apresenta um retângulo fantasma na tela (como na função select object).

getdist(setq DST (getdist "Insira distancia: ")) ;digitar distância ou clicar dois pontos.(setq DST (getdist PT1 "Insira segundo ponto: "))

Page 14: 90784248-Curso-de-Lisp

Deve-se clicar um ponto e a distanca entre este ponto e pt1 será calculada.

Funções getangle e getorient:

getangle(setq ANG (getangle "Angulo de rotação: "))

Pode-se digitar um ângulo em radianos ou pode-se clicar dois pontos. No segundo caso o ângulo obtido será o ângulo que a reta do primeiro para o segundo ponto faz com uma reta imaginária saíndo do primeiro ponto no sentido positivo de x do UCS ativo (obs. reta imaginária ajustada pela variável de sistema ANGBASE).

(setq ANG (getangle PT1 "Angulo de rotação: "))

Deve-se clicar um ponto e o ângulo será calculado como no segundo caso do exemplo acima.

getorient(setq ANG (getorient "Angulo de rotação: "))

Similar a getangle, exceto pelo fato de ignorar a direção do ângulo zero (direção da reta imaginária) contida na variável ANGBASE.Considera zero graus sempre na direção leste (direita).

Funções getkword e initget:

•A função getkword obtem um dígito.•Esta função sempre deve ser precedida da função initget, que restringe a entrada de dados a valores específicos.•Exemplos:

(initget "A B C") (setq OPC (getkword "\nOpcao (A, B ou C)? "))Se algo diferente de A, B ou C for digitado a mensagem INVALID OPTION KEYWORD será apresentada e o programa pausa para nova inserção de dado.

(initget "Y N") (prompt "\nContinue? (Y/N) ") (setq R (getkword))Neste exemplo como getkword não inclui prompt, além da mensagem INVALID OPTION KEYWORD, será apresentada, no caso de digitação incorreta, a mensagem TRY AGAIN:

Função initget em detalhe:

•Sintaxe:(initget [bits] [string])•onde bits pode ser:

•1 (não aceita enter),•2 (não aceita zero),•4 (não aceita valor negativo),•8 (aceita ponto fora do drawing limits)•...

•exemplos de strings:•"S N s n"

Page 15: 90784248-Curso-de-Lisp

•"Sim Não"•"Aprovado Reprovado Exame"

•Exemplos:

(initget 2) ;não aceita zero(initget (+ 1 2 4)) ;não aceita enter, zero ou valor negativo(initget 7) ;equivalente ao exemplo anterior(initget 1 "S N") ;não aceita enter e tem que ser S ou N(initget "10 11 12")

Funções getvar/setvar e getenv:

getvarDescobre qual o valor de uma variável do sistema(setq LAYERATIVA (getvar "clayer"))

setvarAltera o valor de uma variável do sistema.(setvar "clayer" "2D-PAR")

getenvDescobre o valor de uma variável do sistema operacional.(getenv "path")

Convertendo dados:

•Determinadas funções manipulam dados de um tipo específico.•Nem sempre o dado obtido é do tipo exigido pela função que o manipulará.•Portanto, são necessárias funções de conversão entre tipos.

Funções de conversão:

•float - inteiro para real•atoi - string para inteiro•itoa - inteiro para string•atof - string para real•rtos - real para string•angtos - radianos para string•angtof - radianos para real•ascii - string para código na tabela ASCII•chr - código na tabela ASCII para string

A divisão (/ real int) resulta em real. A divisão (/ int int) resulta em int (casas decimais eliminadas).

Exemplo - função com repeat, "gets" e conversões:;;; array inclinado(defun c:arrayincli (/ INICIO FIM INTERVALO DISTANCIA ALPHA NUMREP) (setq INICIO (getpoint "Clique no ponto inicial: ")) (setq FIM (getpoint INICIO "Clique no ponto final: ")) (setq INTERVALO (getdist "Digite distancia entre copias: ")) (setq DISTANCIA (distance INICIO FIM)) (setq ALPHA (angle INICIO FIM))

Page 16: 90784248-Curso-de-Lisp

(setq NUMREP (fix (/ DISTANCIA INTERVALO))) (command "copy" pause "" "0,0" (strcat "@" (rtos INTERVALO) "<" (angtos ALPHA 0 4))) (repeat (- NUMREP 1) (command "copy" "last" "" "0,0" (strcat "@" (rtos INTERVALO) "<" (angtos ALPHA 0 4))) ) )

Funções de impressão:

•princ:•Imprime uma expressão na linha de comando ou num arquivo aberto.•Se a expressão contém caracteres de controle (como \\, \", \e, \n, \t ....). estes são interpretados e executados, i.e.: \n equivale a uma nova linha.

•prin1:•Igual a função princ exceto que caracteres de controle não são interpretados e sim impressos literalmente.

•print:•Igual a função princ exceto que sempre imprime a expressão numa nova linha com um espaço após o que foi impresso.

Função princ - sintaxe e exemplos:

•Sintaxe:

(princ [expressão [nome-de-arquivo]])

•Exemplos:

(setq A 123 B ´(A))(princ 'A) ;imprime A e retorna A(princ A) ;imprime 123 e retorna 123(princ B) ;imprime (A) e retorna (A)(princ "\nOla") ;imprime "Ola" numa nova linha e retorna "Ola"(princ "Ola" f) ;imprime "Ola" no arquivo f e retorna "Ola"

Homework:

•Ler os capítulos 4 e 5 de (Gaál, 1997) ou capítulos 5, 6, 7 e 8 de (Kramer&Kramer, 1995).•Fazer o exericício 4.3.3 (página 61) de (Gaál, 1997), apresentado a seguir:

Para utilização dos recursos de repetição e contadores, crie uma rotina que peça ao usuário que clique um determinado ponto, onde estará supostamente um pilar. Nos pontos clicados, deverá ser gerado o texto no formato Pn, onde n é um número seqüencial representando a numeração do pilar. Caso o usuário desejar, os pilares poderão começar a ser numerados por qualquer valor. Isto deverá ser uma opção a ser apresentada no início do programa.

Page 17: 90784248-Curso-de-Lisp

Aula 4/7 - Programando em AutoLISP

O ambiente de programação VitalLisp

por R. C. Ruschel, DCC-FEC-UNICAMP, Setembro 1997

O ambiente de programação VitalLisp - VILL:

•O software VitalLisp (VILL) é um ambiente de programção para a linguagem AutoLisp do AutoCAD.

•VitalLisp na WWW •e-mail representante no Brasil

•O ambiente de programação VILL é composto por:•editor de texto (colorido ressaltado sintaxe do AutoLisp)•"debugador" - verificador de código:

•mensagens de erro + detalhadas associada a expressão errônea•execução controlada•visualizador de variáveis (watch)

•gerenciador de projetos:•aplicações compostas por + de um arquivo .lsp

Acesso ao VILL pelo AutoCAD:

1.Inicie o AutoCAD2.Carrege o VILL:

•pelo TOOL/Applications:•localize o arquivo VILL.EXE pelo File...•faça um Load

•pela linha de comando digite (xload "c:/vill20.pro/r13/vill.exe")

Obs: o caminho c:/vill20.pro pode variar dependendo da instalação do software. Verifique no seu microcomputador pessoal o caminho correto.

Transitando entre o VILL e o AutoCAD:

•Do AutoCAD para o VILL:•Digite VILL na linha de comando.

•Do VILL para o AutoCAD:•Utiliza o alt+tab do windows.•Se ambas janelas estivirem visíveis clicar na janela desejada.•Clicar no botão com o símbolo do AutoCAD no VILL.

Abrindo um arquivo AutoLisp no editor de texto do VILL:

•Na janela do VILL:1.Clicar FILE OPEN ou no ícone do OPEN

Page 18: 90784248-Curso-de-Lisp

2.Selecionar arquivo .lsp desejado, e.g.: c:\vill20.pro\examples\inyn.lsp3.Clicar OK

•As opções no MENU WINDOW organizam a disposição da janela do editor, e.g.: tile horizontally

O colorido do editor:

•VILL é "color coding", e.g.:•azul: funções internas (car, setq ...)•verde: números•magenta: strings•vermelho: parênteses•preto: símbolos (nome de funções e variáveis definidas pelo usuário)•fundo cinza (background color): comentários

•Ajuda visualizar erros de digitação.

Load de programas .lsp no VILL:

•Como carregar (interpretar, ou executar um load) de um programa .lsp de dentro do editor do VILL:

1.Abrir o programa xxxx.lsp no editor do VILL.2.Clicar no botão LOAD BUFFER3.A janela do console (horizontal inferior) mostrará quantas formas (funções) foram interpretadas, e.g.:;2 forms loaded from ....

Como executar funções:

•No VILL digitar na janela do console (nome-da-função), e.g.:(c:inyn)

Obs: funções sempre devem ser chamadas entre parênteses, mesmo se foram definidas como comando. Somente o AutoCAD interpreta-as como comando.

•No AutoCAD na linha de comando digitar o nome da função, e.g.:command: inyn

Obs: o AutoCAD só consegue executar funções loaded pelo VILL se foram definidas como comando.

Saíndo do VILL:

•Para concluir uma seção de trabalho no VILL escolher no MENU FILE a opção EXIT.

•Se o arquivo .lsp no editor de texto tiver sido alterado sem ter sido salvo, o VILL irá perguntar se deseja salvar o conteúdo do editor. Neste caso deve-se responder SIM ou NÃO.

Debugging - corrigindo programas:

•Erros de programação podem ser de digitação, de sintaxe e/ou lógicos.

Page 19: 90784248-Curso-de-Lisp

•O VILL oferece os seguintes recursos para detectar e corrigir estes erros:•execução controlada do programa,•acompanhamento visual de variáveis,•verificação da pilha de execução do programa,•mensagem de erro detalhada associada a expressão errônea,•editor colorido enfatisando sintaxe da linguagem e•formatador de texto.

Executando um programa no modo debug:

•Um programa em Autolisp é executado no modo debug por expressões entre parênteses (parenthentical expressions).

Obs: um programa em Pascal é executado no modo debug por linha de programação (i.e. por comando).

•Funcionalidades de debugging são controladas de vários lugares do VILL:•do editor,•do console e/ou•de menus.

•Para utilizar estas funcionalidades:•Abrir o programa a ser "debugado" no editor de texto do VILL.•Carregar o programa com LOAD BUFFER.•Colocar um ou mais breakpoints no código do programa.

Colocando breakpoints:

•Breakpoints são pontos de pausa de execução inseridos num programa para possibilitar sua verificação (debugging).

•Como inserir breakpoints:1.Vá para o editor do VILL.2.Posicione o cursor em frente ao parêntese de abertura da expressão desejada.3.Selecione:

•no MENU DEBUG a opção Set Breakpoint ou•na TOOLBAR DEBUG o botão Set Breakpoint.

Executando um programa até um breakpoint:

1.Vá para a janela console do VILL.2.Digite o nome da função a ser executada seguida de um ENTER.3.Responda aos prompts do programa no AutoCAD se necessário.4.Quando o programa alcançar o breakpoint a execução fará uma pausa. Nesse momento pode-se:

•pedir para visualizar variáveis,•executar o programa passo a passo ou•continuar a execuçaõ até outro breakpoint , etc.

Executando o programa passo a passo:

•Estando a execução do programa em pausa num determinado breakpoint:

Page 20: 90784248-Curso-de-Lisp

•Para executar uma expressão selecione STEP na TOOLBAR RUN.•Para entrar numa expressão selecione STEP IN na TOOLBAR RUN.

•Observe o ícone STATUS BUTTON da TOOLBAR RUN que mostra onde o programa está parado, i.e.:

•antes de uma expressão I( ) ou•depois de uma expressão ( )I.

Visualizando o valor de variáveis:

•Estando a execução do programa em pausa num determinado breakpoint:•Selecione no MENU DEBUG a opção Watch Last para visualizar o valor da última variável atualizada.•Selecione com um clique duplo no editor a variável que deseja visualizar e escolha o sinal + na janela WATCH.

•Para retomar a execução de um programa até o final do arquivo ou até outro breakpoint:•Selecione o botão CONTINUE do TOOLBAR RUN.

Como fechar janelas no VILL:

•É possível fechar quase todas janelas no VILL, basta dar um clique-duplo no ícone correspondente (canto superior esquerdo) no cabeçalho da janela.•A única exceção é a janela console do VILL. Essa janela nunca fecha.

Exemplo - Debugando o programa inyno.lsp:

1.Abra o arquivo f:\vill.pro\examples\inyno.lsp pelo MENU FILE/OPEN...2.Este arquivo contém vários erros típicos de programação em Autolisp.3.Veremos como:

•verificar o balanceamento de parênteses,•verificar a sintaxe do programa,•localizar erros de sintaxe através de mensagens de erro,•achar a causa de erros que ocorrem na execução,•se deslocar da pilha de execução com erro para o local do erro no código.

Verificando balanceamento de parênteses:

1.Selecione MENU SOURCE/Format Autolisp in Buffer2.O VILL irá formatar o código.3.Se um casamento errôneo de parênteses for encontrado, a mensagem UNBALANCE OPENING BRACKET FOUND. ADD CLOSING BRACKET? YES/NO será mostrada. Se for respondida comYES, um parêntese é adicionado no final do arquivo. Com certeza este não é o lugar correto do parêntese que está faltando. Portanto, percorra o código no editor na procura do lugar correto. Com o código formatado essa tarefa é facilitada.4.Coloque o parêntese no lugar correto e apague o parêntese acrescentado automaticamente no final do arquivo.5.+ 1 x selecione SOURCE/Format Autolisp in Buffer.

Mecanismos de verificação de parênteses:

Page 21: 90784248-Curso-de-Lisp

•O MENU EDIT oferece os seguintes mecanismos para a verificação de parênteses:•Match Forward: procura o ) correpondente a um abre parêntese.•Match Backward: procura ( correpondente a um fecha parêntese.•Select Forward: ilumina a expressaõ do parêntese de abertura até o correspondente de fechamento.•Select Backward: ilumina a expressaõ do parêntese de fechamento até o correspondente de abertura.

Como verificar a sintaxe de um programa:

1.Vá para o editor do VILL.2.Selecione no MENU SOURCE e a opção CHECK BUFFER.3.Se uma mensagem erro aparecer na janela console é porque existe erro de sintaxe.4.Dê um clique-duplo sobre a mensagem de erro que a expressão errônea no programa é iluminada.5.A mensagem de erro dará uma indicação do tipo de erro que está ocorrendo.

Como utilizar o código colorido para encontrar erros de sintaxe:

•Como vimos anteriormente o código em Autolisp no editor do VILL é colorido. As cores têm significado, e.g.:

•azul = funções internas (car, setq ...)•preto = símbolos (nome de funções e variáveis definidas pelo usuário)•...

•É comum digitarmos errado o nome de uma função interna (e.g. iff para if ou iniget para initget ...). Como sabemos que toda lista de programa inicia com uma subr ou função devemos observar a cor do átomo no início de cada lista. Com certeza na sua maioria será da cor azul.

•Portanto, preste atenção em listas que iniciam com um átomo preto. Verifique se existe um erro de digitação ou se é o nome de uma função definida no programa.

Erros de execução:

•Existem erros que só aparecem durante a execução. Veja o exemplo a seguir:1.Faça um LOAD BUFFER do programa inyno.lsp.2.Execute-o digitando na janela de console (c:inyno).3.Responda no AutoCAD as mensagens necessárais.4.A mensagem de erro aparecerá:;***ERROR: bad argument type for compare: 36.0555 (155.0 155.0 0)

Inspecionando a pilha de execução de um programa:

•Quando um erro de execução ocorrer:1.Selecione no MENU INSPECT a opção INSPECT ERROR TRACE2.Uma janela com o histórico dos cálculos executados surgirá, mostrando no topo a função onde ocorreu o erro e abaixo as chamadas anteriores, até a chamada da função principal.3.Para ir ao local do erro via pilha de execução:

•Selecione a linha na pilha contendo a expressão com o erro.

Page 22: 90784248-Curso-de-Lisp

•Clique o botão da direta do mouse e selecione a opção CALL POINT SOURCE•Faça uma análise, com recursos vistos anteriormente (e.g. visualizando valor de variáveis), da causa do erro indicado .

Como salvar um programa:

•Uma vez editado e ¨debugado¨ um programa deve-se salva-lo.•Vá para o editor do VILL.•Selecione no MENU FILE a opção SAVE.•Confirme o nome do programa e subdiretório onde o programa será salvo.

O manual do VitalLisp:

•Esta aula foi preparada a partir do Capítulo Getting Started do Manual do VitalLisp.•O manual deve sempre ser consultado para se obter melhor desempenho com o software.•O manual é composto pelos seguintes capítulos:

1.Introduction2.Getting started3.The main features fo teh VILL user interface4.The VILL windows5.VitalLisp data inspection tools6.Debugging in VILL7.The VILL Autolisp emulation system8.The Autolisp compiler9.Building stand-alone applications10.Managing multiple lisp files11.The VILL command reference12.Appendix13.Glossary of terms14.Index

Homework:

•Para fixar os comandos do VILL apresentados em aula leia e execute tarefas do capítulo Getting Started do manual do VitalLisp.

•Crie uma função para subtrair uma box de um sólido qualquer. As dimensões da box devem ser dadas clicando-se dois pontos na diagonal na base e o valor da altura. O desenho da box deve ser feito sobre o sólido que sofrerá a subtração. A função desenha a box a ser subtraída. O sólido que sofrerá a subtração deve ser selecionado e a subtração executada pela função.

Page 23: 90784248-Curso-de-Lisp

Aula 5/7 - Programando em AutoLISP

Manipulação de entidades

por R. C. Ruschel, DCC-FEC-UNICAMP, Setembro 1997

Dados das entidades (Kramer&Kramer, 1995 - página 160):

•No Autolisp, o processo de acesso aos dados das entidades estende-se a vários níveis da estrutura do banco de dados do AutoCAD.

•Conjuntos de seleção representam um nível que contém listas de nomes de entidades.•O nome da entidade é um ponteiro para o BD onde os dados referentes à entidade estão armazenados.

•Avançando um nível, os dados de entidades estão na forma de uma lista de associações. Esta hierarquia de dados e a habilidade de trabalhar dentro dela fornece um mecanismo flexível para interfaceamento de aplicativos em Autolisp com a base de dados de desenho do AutoCAD.

Nome da entidade e sua Lista de dados:

•A função entlast obtém o nome da entidade que foi desenhada por último no desenho.•A função entget obtém a lista de dados da entidade a partir de seu nome.

(setq entnome (entlast)) ;retorna <Entity name x...x>(setq entdados (entget entnome)) ;retorna ((-1 . <Entity name x...x>)(0 . "LINE") (8 ."0") ...)

•A lista de dados é uma lista de associações. A maioria destas associações são pares (código . valor) denominados par pontuado (dotted par).

•A lista par pontuado é composta por dois valores (o ponto não conta).

Exercício - lista de dados de uma linha:

•Desenhe uma linha.•Obtenha seu nome: (setq ln(entlast))•Obtenha sua lista de dados: (setq ld(entget ln))•Obtenha o primeiro par pontuado da lista de dados: (setq par1 (car ld))•Obtenha o primeiro átomo do par pontuado: (car par1)•Obtenha o segundo átomo do par pontuado: (cdr par1)

Funções cons, assoc e subst:

•As funções de manipulação de entidade são:•entdel, entget, entlast, entmake, entmod, entnext, entsel, entupd, handent, nentsel, nentselp, tblnext e tblsearch.

Page 24: 90784248-Curso-de-Lisp

•Entretanto, antes de apresentarmos cada uma deve-se conhecer as funções cons, assoc e subst, pois são muito utilizadas em conjunto com as funções de manipulação de entidades.

Função cons:

•Sintaxe:

(cons primeiro-novo-elemento lista)acrescenta um novo elemento no início da lista

(cons primeiro-novo-elemento átomo)constrói uma lista do tipo par pontuado

•Exemplos:

(cons 'a '(b c d)) ;retorna (A B C D)(cons '(a) '(b c d)) ;retorna ((A) (B C D))(cons 'a 2) ;retorna (A . 2)(car (cons 'a 2)) ;retorna A(cdr (cons 'a 2)) ;retorna 2

Função assoc:

•Procura por um elemento numa lista de associações e retorna a lista de associação em que o elemento participa.•Sintaxe: (assoc item lista)•Exemplo:

(setq a1 '((nome box) (largura 3) (comprimento 4.72) (altura 5)))(assoc 'largura a1) ;retorna (largura 3)(assoc 'peso a1) ;retorna nil

Função subst:

•Executa uma substituição de elemento numa lista.•Sintaxe: (subst item-novo item-velho lista)•Exemplos:

(setq lista '(a b (c d) b))(subst 'qq 'b lista) ;retorna (A QQ (C D) QQ) e lista permanece =(setq lista (subst 'qq '(c d) lista)) ;retorna lista modificada para (A B QQ B)(subst '(qq rr) qq lista) ;retorna (A B (QQ RR) B) e lista permanece =

Funções entlast e entsel:

•A função entlast obtém o nome da entidade que foi desenhada por último no desenho.

(entlast) ;retorna <Entity name: x...x>

•A função entsel é similar a função anterior, obtém nome de entidade; entretanto, entsel retorna uma lista composta pelo nome de uma entidade selecionada e o ponto de seleção.

(entsel) ;retorna (<Entity name: x...x> (3.5 5.5 6.8)) e ;a mensagem Select Object: será utlizada.(entsel "\nSelecione um objeto:") ;retorna (<Entity name: x...x> (3.5 5.5 6.8)) e ;a mensagem incluida no prompt da função será utilizada

Page 25: 90784248-Curso-de-Lisp

Função entget:

•Obtém a lista de dados de uma entidade a partir de seu nome.•A lista de dados é uma lista de associações, algumas destas associações são representadas por listas denominadas par pontuado (dotted par).•Uma lista par pontuado é formada por dois átomos (código . valor) separados por um ponto (o ponto não conta como átomo da lista).•Cada código representa um tipo de valor:

•-1 está associado ao nome da entidade•0 está associado ao tipo da entidade "LINE", "ARC" ...•8 está associado ao nome da layer onde a entidade foi desenhada•...

•Ver lista de códigos no Help/Topics/Conteúdo/AutoCAD Customization Guide/Apêndice C -- DXF Group Codes/Conventions/Numerical Order.

Exemplo de uso de entsel, entget e assoc:

•Como obter o nome da layer de um objeto selecionado.

;obtém (<nome-da-entidade> (ponto-de-seleção)) (setq entnome (entsel));obtém lista de dados da entidade selecionada (setq entdados (entget (car entnome)));obtém o par pontuado que contém o nome da layer da entidade (setq par-layer (assoc 8 entdados));obtém o nome da layer da entidade (setq entlayer (cdr par-layer));ou(cdr (assoc 8 (entget (car (entsel))))))

Função entnext e entdel:

•A função entnext retorna o nome da primeira entidade desenhada no desenho ou da próxima entidade com relação a uma entidade determinada.•Exemplos:

;armazena em ent o nome da primeira entidade desenhada no desenho(setq ent (entnext));obtém o nome da entidade desenhada após a entidade determinda(entnext ent)

•A função entdel elemina uma entidade pelo seu nome.

(entdel (entlast)); elimina a última entidade desenhada

Função entmake:

•Cria um novo objeto no desenho a partir de uma lista contendo informações descritivas do objeto.•Sintaxe: (entmake (lista-que-descreve-o-objeto))•Exemplo:

(entmake '( (0 . "LINE")

Page 26: 90784248-Curso-de-Lisp

(8 . "0") (62 . 1) (10 3.0 4.0 0.0) (11 8.0 4.0 0.0) (210 0.0 0.0 1.0) ))

Função handent:

•O handle da entidade é um código único e permanente associado a cada entidade no desenho em qualquer seção de trabalho.•O nome da entidade é um código dado a entidade que muda entre seções de trabalho.•A função handent obtém o nome da entidade a partir do handle da entidade.

(handent "código-do-handle");retorna o nome da entidade

Mudança de nome de entidade:

•Verifique a mudança de nome de entidade entre seções de trabalho com a permanência do mesmo handle:

1.Desenhe um círculo e obtenha sua lista de dados. Anote o nome da entidade e o handle (valor do par pontuado de código 5).2.Salve o desenho e de um open no mesmo desenho.3.+ 1 vez obtenha a lista de dados do círculo. Verifique que o nome da entidade modificou, mas o handle continua o mesmo.

Função nentsel:

•A função nentsel acessa informações de um objeto contido em outro objeto, e.g., objetos que compõem um bloco.•Exercício:

1.Desenhe um bloco formado por um cículo dentro de um retângulo. O ponto de inserção do bloco deve ser o centro do círculo.2.Insira o bloco uma vez.3.Obtenha o nome de entidade da inserção do bloco com (entsel).4.Para se obter o nome da entidade retângulo naquela inserção do bloco utilize (nentsel) e clique sobre o retângulo.5.Para se obter o nome da entidade círculo da mesma inserção do bloco utilize (nentsel) e clique sobre o círculo.6.Observe que na lista retornada por nentsel o primeiro elemento é o nome da entidade componente e o último elemento é o nome da entidade bloco.

Funções entmod e entupd:

•A função entmod altera as características de uma entidade.•A função entupd atualiza a exibição de uma entidade alterada por entmod.

•entupd só é necessária para alterar exibição de entidade compostas alteradas, e.g. polylines.•no caso de entidade simples, e.g. círculos, arcos e etc, a própria entmod atualiza caracteristicas e visualização.

Page 27: 90784248-Curso-de-Lisp

Exemplo do uso de entmod:

•Função que altera o raio de um círculo:

(defun c:raio () (setq vl (getreal "Novo raio: ")) (setq sair "N") (while (= sair "N") (setq ent (car (entsel "\nClique o circulo a ser modificado: "))) (setq dados (entget ent)) (print dados) (setq dados (subst (cons 40 vl) (assoc 40 dados) dados)) (entmod dados) (initget 1 "S N") (prompt "\nSair? (S/N) ")(setq sair (getkword)) ))

Funções tblnext e tblsearch:

•Pesquisa as tabelas de informações num desenho sobre os seguintes recursos:•LAYER, LTYPE, VIEW, STYLE, BLOCK, UCS, APPID, DIMSTYLE e VPORTS.•Obs: na tabela de informações sobre layers de um desenho cada layer definida compõe uma linha da tabela.•O mesmo é válido para cada recurso enumerado acima.

•A função tblnext percorre linha por linha da tabela:

(tblnext "layer" T);retorna lista com primeira linha da tabela layers(tblnext "layer");retorna lista com a linha seguinte da tabela layers

•A função tblsearch procura por um ítem na tabela:

(tblsearch "layer" "2d-par");retorna infos sobre layer 2d-par

Exercício:(defun c:tbllayer () ;obtenha a primeira linha da tabela de layers do desenho ;imprima a lista retornada ;enquanto não chegar no final da tabela (i.e. retorno de tblnext \= nil) ;obtenha proxima linha ;imprima lista retornada ;fim-do-enquanto)

Crie uma função tblltype, equivalente a acima, para tipos de linhas (LTYPES).

Homework:

•Ler os capítulos 5 e 6 de (Gaál, 1997) ou o capítulo 10 de (Kramer&Kramer, 1995).•Fazer o exercício 6.3.2 (página 96 de Gaál, 1997), apresentado a seguir:

Page 28: 90784248-Curso-de-Lisp

Crie uma função que, com base num círculo clicado, faça o desenho de uma flange apresentada abaixo, seguindo as relãções entre as medidas cotadas: (número de furos constante = 10).

Page 29: 90784248-Curso-de-Lisp

Aula 6/7 - Programando em AutoLISP

Conjuntos de seleção

por R. C. Ruschel, DCC-FEC-UNICAMP, Outubro 1997

Conjuntos de seleção:

•Cada vez que um item (ou grupo de items) é manuseado no AutoCAD, um conjunto de seleção está em operação.•Conjuntos de seleção são listas especiais que contêm os nomes das entidades dos itens selecionados.•No AutoLisp um conjunto de seleção é definido como um tipo de dado, assim como um real, integer ...•O AutoLisp permite a criação de até 128 conjuntos de seleção por aplicação.

Como criar um conjunto seleção:

•As funções ssadd e ssget criam conjuntos seleção dentro de programas em AutoLisp.•Exemplo com a função ssadd:

(setq ss1 (ssadd));cria um conjunto seleção vazio(ssadd (entlast) ss1); inclui o nome da última entidade criada no conjuntoseleção ss1(setq ss2 ss1)

Garbage collection (remoção de lixo):

•Mais de uma variável pode estar associada ao mesmo conjunto seleção. Veja o exemplo anterior, ss1 e ss2 apontam para o mesmo conjunto.•Se estas duas variáveis forem ajustadas para nil e forem as únicas a apontarem para o conjunto seleção em questão, então é necessário liberar o espaço de memória que o conjunto seleção está ocupando.•Essa atividade é denominada garbage collection e é executada pela função gc.•Exemplo:

(setq ss1 nil ss2 nil)(gc); libera espaço de memória de qualquer conjunto seleção não associado a variáveis.

Função ssadd:

•Cria um conjunto seleção vazio ou acrescenta entidades a um conjunto existente.•Sintaxe:(ssadd [nome-de-entidade [conjunto-seleção]])

•sem opções cria conjunto seleção vazio•apenas com opção nome-de-entidade cria conjunto seleção composto pela entidade especificada•com opções nome-de-entidade e conjuto-seleção acrescenta entidade a um conjunto seleção existente.

Page 30: 90784248-Curso-de-Lisp

•Exemplo:

(setq ss1 (ssadd)) ;retorna <Selection set: XX>

Função ssget:

•Cria um conjunto seleção a partir de uma seleção de objetos.•Sintaxe:(ssget [mode] [pt1] [pt2] [pt-list] [filter-list])

•onde mode: "P" (previous), "L" (last), "W"(window), "C" (crossing), "X" (all), "WP" (window poligon), "CP" (crossing poligon), "F" (fence).

•Exemplos:

(ssget "X") ;cria conjunto seleção com todas entidades do desenho(ssget "W" pt1 pt2);cria conj. sel. com objetos contidos na janela definida por pt1 e pt2(ssget '((0 . "LINE"))); conj. sel. de linhas selecionadas individual/e

Exemplo de funções com ssget:;;; conjunto seleção das entidades dentro da janela(defun c:seleciona-janela (/ p1 p2) (setq p1 (getpoint "\nPrimeiro canto:")) (setq p2 (getcorner p1 "\nSegundo canto:")) (setq ss1 (ssget "W" p1 p2)))

;;;conjunto seleção com todas linhas do desenho(defun c:ssline () (setq lineobjs (ssget "X" '((0 . "LINE")))))

Utilizando conjuntos seleção:;;; erase all(defun c:eall (/ ssall) (setq ssall (ssget "X")) (command "erase" ssall "") (command "redraw") (setq ssall nil)(gc) (princ))

Funções sslenght e ssname:

•A função sslength retorna o número de entidades que compõem um conjunto seleção.•Sintaxe: (sslength conjunto-seleção)

•A função ssname retorna o nome da entidade na posição x de um conjunto seleção.•O primeiro elemento um conjunto seleção está na posição 0.•Sintaxe: (ssname conjunto-seleção posição)

Exemplo de função com sslength e ssname:

Page 31: 90784248-Curso-de-Lisp

(defun c:sslist () (setq grupo (ssget)) (print grupo) (setq num (sslength grupo)) (print num) (setq cont 0) (repeat num (setq nome (ssname grupo cont)) (print cont) (princ nome) (setq cont (1+ cont)) ) (princ))

Mais um exemplo - função que seleciona maior linha:(defun c:maior (/ gru num cont maior inicio fim dista mai-ent) (setq gru (ssget "X" '((0 . "LINE")))) (setq num (sslength gru)) (setq cont 0) (setq maior 0) (repeat num (setq inicio (cdr (assoc 10 (entget (ssname gru cont))))) (setq fim (cdr (assoc 11 (entget (ssname gru cont))))) (setq dista (distance inicio fim)) (if (>= dista maior) (progn (setq maior dista) (setq mai-ent (ssname gru cont)) ) ) (setq cont (1+ cont)) ) (alert "Clique OK para destacar\n a maior linha...") (redraw mai-ent 3) (gc))

Exercício:

•Defina uma função denominada ssredraw. A função tem como parâmetro de entrada o nome de um conjunto seleção. A função deve aplicar um redraw com código 3 em todas entidades que participam do conjunto seleção especificado.

•A sintaxe da função redraw é (redraw nome-de-entidade código).•Redefina a função c:seleciona-janela apresentada anteriormente incluindo uma chamada para a função ssredraw. Desta forma, os objetos selecionados serão destacados.

Função ssmemb:

•A função ssmemb verifica se uma determina entidade pertence a um conjunto seleção.•Se a entidade pertence ao conjunto seu nome é retornado, senão a função retorna nil.•Sintaxe:(ssmemb nome-da-entidade conjunto-seleção)•Exemplo:

(setq ss1 (ssget))

Page 32: 90784248-Curso-de-Lisp

(ssmemb (car (entsel)) ss1)

Função ssdel:

•A função ssdel remove uma entidade de um conjunto seleção.•OBS: a entidade não é apagada do desenho.

•Sintaxe: (ssdel nome-da-entidade conjunto-seleção)•Exemplo:

(setq ss1 (ssget))(ssdel (car (entsel)) ss1)

Homework:

•Ler os capítulos 7 e 8 de (Gaál, 1997) ou o capítulo 10 de (Kramer&Kramer, 1995).

Page 33: 90784248-Curso-de-Lisp

Aula 7/7 - Programando em AutoLISP

Funções Geométricas e Manipulação de Arquivos

por R. C. Ruschel, DCC-FEC-UNICAMP, Outubro 1997

Funções geométricas:

•As funções geométricas do Autolisp são: distance, angle, polar, inters, cal, osnap e trans•Essas funções permitem:

•desenhar rapidamente com precisão•efetuar cálculos envolvendo objetos desenhados•obter o máximo de informação partindo do desenho•permitir que o usuário entre com o mínimo de dados para que entidades sejam criadas

Função distance:

•Obtém a distância entre dois pontos.•Sintaxe:(distance ponto1 ponto2)•Exemplo:

(setq p1 (getpoint "\nInsira um ponto:"))(setq p2 (getpoint "\nInsira outro ponto:"))(setq d (distance p1 p2))

Função angle:

•Obtém o ângulo em radianos de uma reta definida por dois pontos e o eixo X do UCS ou WCS corrente, medido no sentido anti-horário.•Sintaxe:(angle ponto1 ponto2)•Exemplo:

(setq p1 (getpoint "\nInsira um ponto:"))(setq p2 (getpoint "\nInsira outro ponto:"))(setq a (angle p1 p2))

Função polar:

•Retorna um ponto em 3D do UCS corrente a partir de um ponto, ângulo (em radianos) e distância especificados.•Sintaxe:(polar ponto ang dist)•Exemplo:

(setq p1 (getpoint "\nInsira um ponto:"))(setq p2 (polar p1 0.785398 1.414214))

Page 34: 90784248-Curso-de-Lisp

Função inters:

•Obtém interseção de duas retas definidas cada uma por dois pontos.•Sintaxe:(inters pnt1-r1 pnt2-r1 pnt1-r2 pnt2-r2)•Exemplo:

(setq p1r1 (getpoint "\nInsira um ponto1 da primeira reta:"))(setq p2r1 (getpoint "\nInsira outro ponto:"))(setq p1r2 (getpoint "\nInsira um ponto1 da segunda reta:"))(setq p2r2 (getpoint "\nInsira outro ponto:"))(setq pint (inters p1r1 p2r1 p1r2 p2r2))

Função osnap:

•Retorna um ponto em 3D do UCS corrente resultado da aplicação de uma função de precisão sobre um ponto especificado.•As funções de precisão são:end, mid, int, appint, cen, qua, per, tan, nod, ins, nea ...•Sintaxe:(osnap ponto "precisão")•Exemplo:

(defun c:pontomediano (/ pt) (setq pt (getpoint "\Clique sobre uma reta:")) (setq pt (osnap pt "nea")) (setq ptmid (osnap pt "mid")))

Função trans:

•Translada um ponto de um sistema de coordenadas para outro sistema de coordenadas.•Sintaxe:(trans pnt sc-orig sc-dest [disp])

•sc-orig e sc-dest espeficam os sistemas de coordenadas original e destino. Estes argumentos podem ser:

•códigos (0 para WCS,1 para UCS corrente, 2 para UCS do view, 3 para paperspace)•nomes de entidade (obtidos com entnext, entlast, entsel, nentsel e ssname)•um vertor de extrusão em 3D

•disp se presente e não-nulo especifica que pnt deve ser tratado com um deslocamento em 3D e não um ponto.

Função trans - exemplos:

•Se o UCS corrente foi obtido da mudança de origem para 10,10,10 então:

(setq p (list 0 0 0))(trans p 0 1) ;retorna (-10.0 -10.0 -10.0)(trans p 1 0) ;retorna (10.0 10.0 10.0)

•Para se converter pontos em 2D para 3D:

Page 35: 90784248-Curso-de-Lisp

(setq ponto (list 1 2))(trans ponto 0 1);acrescenta z=0 no ponto(trans ponto 1 0);acrescenta z = z do UCS corrente no ponto

Exemplo - funções trans e polar:(defun c:tr (/ centro1 centro2 ncentro dia) (command "ucs" "") ;ajustando ucs para wcs (setq centro1 (getpoint "Escolha o centro da rotação:")) (setq dia (getreal "Diametro do círculo:")) (setq centro2 (polar centro1 0 (* 2 dia))) ;centro do primeiro círculo (command "circle" centro2 (/ dia 2)) ;desenhando 1o. círculo centro+raio (repeat 10 (command "ucs" "y" "36") ;gira ucs entorno do eixo y 36graus (setq ncentro (trans centro1 0 1)) ;transladanco centro1 para novo ucs (setq centro2 (polar ncentro 0 (* 2 dia))) ;centro do próximo círculo (command "circle" centro2 (/ dia 2)) ;desenhando próximo círculo ) )

Manipulação de arquivos ASCII:

•A manipulação de arquivos consiste em armazenar informações obtidas durante uma sessão do AutoCAD em arquivos para uso posterior.•O Autolisp permite que dados sejam gravados e lidos a partir de arquivos escritos no padrão ASCII.•As funções de manipulação de arquivos ASCII pelo Autolisp são:

•de abertura e fechamento de arquivo: open e close•de leitura: read-char e read-line•de escrita: write-char, write-line, princ, print, prin1

Abrindo arquivos:

•Quando um arquivo ASCII é aberto pelo Autolisp, o registro da sua abertura deve ficar gravado numa variável especificada no programa.•Essa variável representa o arquivo dentro do programa. Sempre que se deseja referir ao arquivo dentro do programa, deve-se referir a essa variável.•Um arquivo pode ser aberto para:

•leitura•escrita•leitura e escrita

Função open:

•Sintaxe:(open "unidade:\\subdir\\arquivo.txt" "código")•onde "código" pode ser:

•r (para leitura),•w (para escrita) e

Page 36: 90784248-Curso-de-Lisp

•a (para leitura e escrita)•Exemplos:

(setq LE (open "c:\\lista.txt" "r"))(setq GRAVA (open "c:\\trab\\lista.txt" "w"))(setq INCRE (open "c:\\tmp\\lista.txt" "a"))

Funções de escrita em arquivos ASCII:

•As funçoes write-char, write-line, princ, print e prin1 escreverm (gravam) informações em um arquivo ASCI aberto para escrita ou leitura e escrita.•Sintaxe: (comando-de-escrita informação arquivo)•Exemplo:

(defun c:abrearq () ;abre arquivo para escrita e zera conteúdo se arquivo já existia (setq arq (open "c:\\trab\\arquivo.txt" "w")) (princ "FEC215 - Curso de Extensçao " arq) (setq ano 1997) (princ ano arq) (write-line "utilizando autocad r13 windows" arq) (close arq))

Comandos de leitura:

•As funções read-line e read-char são funções que lêem dados de arquivos ASCII.•Sintaxe: (read-line arquivo) ;retorna linha lida (read-char arquivo) ;retorna código do caracter lido•Exemplo:(setq caracter (chr (read-char arq)))

Exemplo - função read-line:(defun c:learq () (setq arq (open "c:\\trab\\arquivo.txt" "r")) (if (= arq nil) (alert "Open Inválido!") (progn (setq linha (read-line arq)) (while (/= linha nil) (print linha) (setq linha (read-line arq)) ) ) ) (princ))

Homework:

•Ler os capítulos 7 e 8 de (Gaál, 1997) ou o capítulo 10 de (Kramer&Kramer, 1995).•Exercício 8.3.2 sugerido por Gaál na página 119:

Page 37: 90784248-Curso-de-Lisp

Crie uma função que, tendo como base o desenho de um pilar formado por quatro linhas, insira um texto indicando as suas dimensões (ex. P1 (20x50), P2 (60x30))

Página confeccionada por RCR. Última atualização em 15-10-1997.