Identificar Texto dentro de um Polígono / Polyline Fechada

Identificar Texto dentro de um Polígono / Polyline Fechada

Anonymous
Não aplicável
2.469Exibições
11Respostas
Mensagem 1 de 12

Identificar Texto dentro de um Polígono / Polyline Fechada

Anonymous
Não aplicável

Boa tarde.

Pesquisei no google e aqui no forum, mas não encontrei como identificar textos dentro de uma Polyline fechada.
Eu preciso capturar o valor do texto que está dentro do polígono (no desenho existem vários polígonos, alguns com texto no interior outros não) para ser um dos parâmetros que irá gerar uma layer para esse mesmo polígono.

Algum(a) dos senhores/senhoras sabe como faço isto através de LISP?

Desde já, agradeço pela ajuda.

2.470Exibições
11Respostas
Respostas (11)
Mensagem 2 de 12

f_santana
Mentor
Mentor

faça uma captura dos vertices do piligono e gere uma lista

depois use estes pontos para fazer uma seleção


Você achou uma postagem útil? Então fique à vontade para curtir essas postagens!
Sua pergunta obteve uma resposta que resolveu a duvida? Então clique no botão Aceitar Solução.


Fábio Santana
Architect | CAD/BIM Manager

EESignature

Mensagem 3 de 12

Anonymous
Não aplicável

Muito obrigado Fábio, acredito que para esse procedimento seja mais fácil encontrar material.

Vou tentar fazer e depois posto o resultado.

0 Curtidas
Mensagem 4 de 12

RenatoDonatoViana
Advisor
Advisor
Diego,

Boa tarde!

Lendo sua postagem, gostaria de saber se o que deseja é somente através de rotinas, pois existem outras formas de você conseguir obter essas informações, porém do modo manual.

Abraços,
Renato Donato Viana

Você achou esse post útil? Sinta-se à vontade para curtir.
Esta postagem respondeu com sucesso à sua pergunta? Clique no botão ACEITAR SOLUÇÃO.

EESignature



Mensagem 5 de 12

hmsilva
Mentor
Mentor

diego.teixeira escreveu:

Boa tarde.

Pesquisei no google e aqui no forum, mas não encontrei como identificar textos dentro de uma Polyline fechada.
Eu preciso capturar o valor do texto que está dentro do polígono (no desenho existem vários polígonos, alguns com texto no interior outros não) para ser um dos parâmetros que irá gerar uma layer para esse mesmo polígono.

Algum(a) dos senhores/senhoras sabe como faço isto através de LISP?

Desde já, agradeço pela ajuda.


Olá Diego,

em adição ás sugestões do Fábio, tens que ter em atenção que os métodos de seleção gráficos (ssget 'Crossing = C e CP' 'Fence = F' 'Window = W e WP') têm que ter o/s objeto/s a selecionar visiveis no monitor...

Uma maneira de lidar com este constrangimento é fazer um zoom utilizando as mesmas coordenadas da seleção (ou zoom object) antes se se selecionar.

 

Uma outra maneira de se testar se o texto está dentro de um polígono, poderá ser testando com uma série de RAYs (em 360 graus) criados para teste usando o ponto de inserção do texto e utilizando o método 'IntersectWith' entre os RAYs e a polilinha, se todos os testes forem T quer dizer que está dentro desta... Este método não necessita de se colocar a polilinha visivel...

 

Espero que ajude
Henrique

EESignature

Mensagem 6 de 12

Anonymous
Não aplicável

Bom dia Renato.

 

Tem que ser através de rotinas, são muitos arquivos em CAD e cada arquivo possui vários polígonos.

Preciso gerar uma layer diferente para cada polígono que possui esse texto numérico dentro, esse texto serve como um dos valores usados para gerar o código que nomeará a layer.

 

Eu tenho uma lisp que cria as layers e coloca os polígonos dentro de suas respectivas layers, mas o valor que existe dentro de cada polígono eu tenho que digitar, isso é um problema, pois demanda mais tempo e está sujeito a erro de digitação.

 

De qualquer forma, muito obrigado!

0 Curtidas
Mensagem 7 de 12

hmsilva
Mentor
Mentor

Diego,

'rápido e sujo' e apenas como exemplo...

 

Utilizei uma sub-função do GP_ 'inside_p' e para simplificar o código e o tempo de execução utilizei filtro de LAYER tanto para o textto como para as polylines.

LAYER das poly = poly

LAYER dos textos = text

 

(vl-load-com)
(defun c:demo (/ inside_p i Lv m n nome poly polys poly_ent pt r sspoly sstext txt txt_ent)

    ;; by GP_
    ;; http://www.cadtutor.net/forum/showthread.php?84483-Check-if-a-point-is-inside-an-area-bounded-by-a-polyline&p=578928&viewfull=1#post578928
    (defun inside_p (list_vert :p / out_p cross on)
        (setq out_p (list (car (getvar "extmax")) (* 1.1 (cadr (getvar "extmax")))))
        (setq cross 0)
        (mapcar
            '(lambda (a b)
                 (if (or
                         (equal (angle a :p) (angle :p b) 1e-8)
                         (equal a :p 1e-8)
                     )
                     (setq on t)
                 )
                 (if (setq :p: (inters :p out_p a b))
                     (setq cross (1+ cross))
                 )
             )
            list_vert
            (cdr list_vert)
        )
        (cond
            (on "ON")
            ((> (rem cross 2) 0) "INSIDE")
            (t "OUTSIDE")
        )
    )

 ;-------- main function ----------

    (if (and (setq sstext (ssget "_X" (list '(0 . "text") '(8 . "text") (cons 410 (getvar 'CTAB)))))
             (setq sspoly (ssget "_X" (list '(0 . "lwpolyline") '(-4 . "&=") '(70 . 1) '(8 . "poly") (cons 410 (getvar 'CTAB)))
                          )
             )
        )
        (progn
            (repeat (setq i (sslength sstext))
                (setq txt     (ssname sstext (setq i (1- i)))
                      txt_ent (entget txt)
                      pt      (cdr (assoc 10 (entget txt)))
                      polys   (1- (sslength sspoly))
                      m       0
                      r       nil
                )
                (while (and (null r)
                            (<= m polys)
                       )
                    (setq poly (ssname sspoly m)
                          Lv   nil
                    )
                    (repeat (setq n (1+ (fix (vlax-curve-getEndParam poly))))
                        (setq Lv (cons (vlax-curve-getPointAtParam poly (setq n (1- n))) Lv))
                    )
                    (if (/= (inside_p Lv pt) "OUTSIDE")
                        (progn
                            (setq r        T
                                  poly_ent (entget poly)
                                  nome     (cdr (assoc 1 txt_ent))
                            )
                            (entmake (list '(0 . "LAYER")
                                           '(100 . "AcDbSymbolTableRecord")
                                           '(100 . "AcDbLayerTableRecord")
                                           (cons 2 nome)
                                           '(70 . 0)
                                     )
                            )
                            (entmod (subst (cons 8 nome) (assoc 8 poly_ent) poly_ent))
                        )
                        (setq m (1+ m))
                    )
                )
            )
        )
    )
    (princ)
)

 

Espero que ajude
Henrique

EESignature

Mensagem 8 de 12

Anonymous
Não aplicável

Henrique, funcionou muito bem. Obrigado!

 

Mas minha intenção é incorporar em uma lisp que eu tenho e ao poucos ir aprendendo, se você puder comentar as principais linhas me ajudaria muito na hora de incluir seu código na lisp que eu tenho, eu acho que é pertinente e ajudaria se eu colocar o código da LISP que estou editando aqui.

 

 

;ESTE PROGRAMA GERA UM LAYER PARA CADA TALHAO A PARTIR
;DA DIGITACAO DO BLOCO E O NUMERO DO TALHAO

;^C^C(load "C:/Path/GERA_AUTO_LAYER.lsp") ga

;========================================================================
(defun c:ga ()
   (SETVAR "CMDECHO" 0)
   (SETVAR "BLIPMODE" 0)
   (command "grid" "off")
   (COMMAND "STYLE" "ROMANC" "ROMANC.SHX" "10" "1" "" "" "" "")

  ;(initget (+ 1 2 4))
  ;(SETQ SET (GETINT "\nENTRE COM O CODIGO DO SETOR SEM ESPAÇOS: "))
  ; (SETQ SET1 (ITOA SET))
  ;      (setq d1 (strcat "00" SET1));soma 2 zeros ao codigo da setor
  ;      (setq caracter1 (strlen d1));retorna o numero de caracter
  ;      (setq num (- caracter1 1));posicao onde inicia a string
  ;      (setq SET2 (substr d1 num 2));retorna o codigo do setor com 2 casas

   (initget (+ 1 2 4))
   (SETQ NOME (GETINT "\nDigite o código da nomenclatura sem espaços (4 dígitos): "))
   (SETQ NOME1 (ITOA NOME))
        (setq d1 (strcat "0000" NOME1)) ;soma 4 zeros ao codigo da nomenclatura
        (setq caracter1 (strlen d1)) ;retorna o numero de caracter
        (setq num (- caracter1 3)) ;posicao onde inicia a string
        (setq NOME2 (substr d1 num 4)) ;retorna o codigo da fazenda com 4 casas
  
   (setq RESP "S")
   (while (= RESP "S")
  
  	(initget (+ 2 4))
   	(SETQ BLOCO (GETINT "\nDigite o código do bloco sem espaço (3 dígitos): "))
     	(if (= BLOCO NIL)
	  	(PROGN
		  	;Move todos os objetos da camada "0" para frente.
   			(setq sel1 (ssget "x" '((8 . "0")))); Cria uma seleção em todos os objetos da layer "0".
   			(command "draworder" sel1 "" "front");Usa o comando draworder para mover os objetos para frente.
   			(COMMAND "chprop" sel1 "" "lw" "0.5" "")
		  	(command "_.pedit" "_m" sel1 "" "w" 3 "")
	  		(EXIT)
		  )
	)
   	(SETQ BLOCO1 (ITOA BLOCO))
        	(setq d1 (strcat "000" BLOCO1)) ;soma 3 zeros ao codigo do bloco
        	(setq caracter1 (strlen d1)) ;retorna o numero de caracter
        	(setq num (- caracter1 2)) ;posicao onde inicia a string
        	(setq BLOCO2 (substr d1 num 3)) ;retorna o codigo do setor com 3 casas

   	(setq BASE (strcat NOME2 BLOCO2)) ;concatena a nomenclatura com o bloco para formar a base do nome do layer

   	(COMMAND "OSNAP" "NONE")

   	(PRINT "Selecione os talhões que fazem parte do bloco")
   	(SETQ COD_TAL (SSGET (LIST (CONS 0 "LWPOLYLINE"))));seleciona todas as polilinhas
   	(COMMAND "chprop" COD_TAL "" "c" "3" "")
			   
   	(if (/= COD_TAL NIL)
      		(PROGN        
         		(PRINT "teste 1")
         		(SETQ NUM_IDENT (SSLENGTH COD_TAL))
         		(SETQ IDENT_NUM 0)
         
         		(WHILE (< IDENT_NUM NUM_IDENT)
            
            			(SETQ COD_TAL1 (SSNAME COD_TAL IDENT_NUM))

            			(COMMAND "chprop" COD_TAL1 "" "c" "1" "")

			  	(if (= IDENT_NUM 0)
				  	(PROGN
			  			(initget (+ 1 2 4))
            					(SETQ NUMERO_TAL (GETINT "\nDigite o número do talhão inicial : "))
			  			(SETQ IDENT_NUM2 NUMERO_TAL)
					)
            			)  

            			(SETQ NUMERO_TAL (* IDENT_NUM2 10));multiplica o número de talhão por 10, para gerar o final da layer
            			(SETQ NUMERO_TAL (ITOA NUMERO_TAL))

			  	(setq d1 (strcat "0000" NUMERO_TAL ));soma 4 zeros ao codigo do talhao
				(setq caracter1 (strlen d1));retorna o numero de caracter
				(setq num (- caracter1 3));posicao onde inicia a string
				(setq NUMERO_TAL (substr d1 num 4));retorna o codigo da fazenda com 4 casas

				(setq LA_CAR (STRCAT BASE NUMERO_TAL))   
	  
	            		(IF (NOT (TBLSEARCH "LAYER" LA_CAR));se nao existir o layer ele cria 
	                		(COMMAND "LAYER" "NEW"  LA_CAR "")
	            		)
	 
	            		(COMMAND "chprop" COD_TAL1 "" "LA" LA_CAR "")
	 
	            		(COMMAND "chprop" COD_TAL1 "" "c" "4" "");MUDA A COR DO TALHAO PARA AZUL

	            		(SETQ IDENT_NUM (+ IDENT_NUM 1))
			  	(SETQ IDENT_NUM2 (+ IDENT_NUM2 1))
			  	(princ "\n3")
			  	;(PRINT "3");--------
         		)
      		)      
   	)
     	(setq RESP "S")
      
   	;(SETQ MUDACOR (SSGET "X" (LIST (CONS 8 SETOR))));seleciona todas as polilinhas
   	;(COMMAND "chprop" COD_TAL "" "c" "BYLAYER" "")
   	(COMMAND "chprop" COD_TAL "" "c" "2" "")

          
   )
   ;Move todos os objetos da camada "0" para frente.
   (setq sel1 (ssget "x" '((8 . "0")))); Cria uma seleção em todos os objetos da layer "0".
   (command "draworder" sel1 "" "front");Usa o comando draworder para mover os objetos para frente.
   (COMMAND "chprop" sel1 "" "lw" "0.5" "")
   
  
   (COMMAND "PURGE" "ALL" "" "N") 
   (PRINC)
)

Era preciso digitar todos os códigos para formar a layer, consegui (não sei se da forma correta) automatizar alguns processos, usando laço de repetição e incrementando automaticamente o valor usados para gerar as layers, mas há layers que possuem prefixo iguais e final não sequencial, conforme imagem, e da forma que eu fiz é preciso entrar novamente com o segundo código "

(SETQ BLOCO (GETINT "\nDigite o código do bloco sem espaço (3 dígitos): "))

"

selecionar os poligonos pertencentes à ele informar qual o valor do 1º poligono para assim incrementar. Segue imagem:

 

DES_CAD.png

 

Creio que assim fica mais fácil de todos entenderem, eu sempre procuro compreender o que estou usando para que se tiver outra dificuldade parecida, consiga fazer os ajustes necessários para resolver.

 

Agradeço muito pela ajuda.

 

0 Curtidas
Mensagem 9 de 12

hmsilva
Mentor
Mentor

Olá Diego!

Já estou fora do escritório e de férias... 😞

Vou estar fora a proxima semana e (segundo a minha mulher, sem laptop....)

 

Mas tenta anexar um dwg de exemplo, que se eu conseguir vejo o que dá para fazer.

 

Não compreendo como é atribuido o código da parcela, existe alguma delimitação fisica desse código, ex. uma polilinha de limite?

Existe essa informação escrita no desenho?

 

Henrique

EESignature

Mensagem 10 de 12

Anonymous
Não aplicável

Senhores, bom dia.

 

Não sei o que houve, na sexta-feira postei o arquivo e expliquei o passo-a-passo como o Henrique pediu, hoje vejo que a mensagem não aparece e o tópico foi marcado como solucionado.

 

Enviarei novamente o arquivo e a descrição de como a layers são geradas.

 

 

0 Curtidas
Mensagem 11 de 12

Anonymous
Não aplicável

Bom dia à todos, segue novamente a mensagem...

 

Antes de tudo, boa férias Henrique! 

(o que você fez à patroa para que ela desse esse castigo (sem laptop)? rs)

 

Está em anexo o mesmo arquivo usado para fazer a imagem da mensagem acima.

 

As informações usadas para gerar o nome da layer são:

- O número que está no campo "código" do bloco de texto perto dos polígonos;

- O número existente dentro do polígono, que pertence ao grupo do campo código.

 

Por exemplo, se pegarmos a 1ª Layer gerada: 02290100140.

 

Para obter esse número, olhamos o primeiro número do campo código que está no bloco, 229010, e adicionamos o número 14, que é um dos números que pertence a este número. Por questão de padronização, este código gerado para a layer precisa ter 11 dígitos, sendo 4 identificando o arquivo (no caso, 0229), 3 identificando um bloco de polígonos (no caso, 010) e 4 identificando o código do polígono (neste exemplo, 0140).

 

A lisp funciona da seguinte maneira (seguindo o exemplo):

- Inicialmente pede-se para informar o código da nomenclatura (digito 0229 ou 229, pois ela acrescenta zeros à esquerda para gerar 4 dígitos);

- Depois ela pede para informar o código do bloco (digito 010 ou 10, pois ela acrescenta zeros à esquerda para gerar 3 dígitos);

- Então pede que selecione os elementos sequenciais que fazem parte desse bloco;

- Na sequência informamos qual o primeiro número da sequência (14, pois ela acrescenta 1 zero à esquerda e os zeros necessários à direita para formar 4 dígitos); É esse processo que agora eu quero melhorar, pois quando tenho polígonos não sequenciais pertencentes ao mesmo bloco, tenho que repetir o processo várias vezes.

- Cria-se as layers e os polígonos correspondentes são atribuídos as layers;

 

Espero ter explicado bem, se precisarem de mais informações, estou à disposição.

 

0 Curtidas
Mensagem 12 de 12

Anonymous
Não aplicável

Boa tarde.

 

Se alguém conseguir me dizer o que fazem as principais linhas do algoritmo que o Henrique fez, acho que consigo incorporar na lisp que tenho.

Por exemplo, se eu conseguir entender as linha que capturam e armazenam o valor do texto dentro do polígono, dá para usar essa parte na lisp que postei.

 

Grato.

0 Curtidas