AutoCad - rutina con error

 
Vista:

rutina con error

Publicado por JORGE VERGARA C (6 intervenciones) el 02/04/2020 19:03:37
Alguien me puede ayudar con este codigo, que lo reviso y dentro de su logica esta bien, pero no se en que momento falla y no realiza lo que debe, esta rutina dibuja una polylinea y el luego el programa pide indicar dos puntos en pantalla sobre cualquier punto de la linea y debe dibujar dos textos sonbre dicho elemento, obviamente se hace una operacion para que el proximo punto de la ubicacion del texto que sobre la linea, al principio funciona bien, pero despues de unas par de veces vuelve a dibujar los textos sobre la polilynea, espero me puedan indicar conde esta el error, o la manera de sobrescrbir codigo, aca dejo codigo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
(Defun Limpia()
  (Repeat 3 (Prompt "Command: ") (Print))
)
 
 
(Defun C:L2()
 
  (Setq Layer_Linea             "Linea_electrica")
  (Setq Color_Linea             7)
  (Setq Layer_Texto             "Linea_electrica")
  (Setq Color_Texto             7)
  (Setq Altura_Texto            1.5)
  (Setq Estilo                  "ROMANS")
  (Setq Justificacion           "Middle")
  (Setq Distancia_Texto_Linea   1.0)
 
  (Command "layer" "n" Layer_Linea "c" Color_Linea Layer_Linea "")
  (Command "layer" "n" Layer_Texto "c" Color_Texto Layer_Texto "")
 
  (Command "osnap" "ins")
(Limpia)
(Setq Punto_Inicio (Getpoint "Seleccione Primer Punto Inicio :"))
  (If Punto_Inicio
    (Progn
        (Limpia)
        (Setq Punto_Fin (Getpoint Punto_Inicio "Seleccione Segundo Punto Fin :"))
 
              (Command "Pline" Punto_Inicio Punto_Fin "")
              (Command "Chprop" "Last" "" "LA" Layer_Linea "")
              (Limpia)
              (Setq Distancia (Distance Punto_Inicio Punto_Fin))
              (Setq Valor_Texto Distancia)
              (Setq Angulo_Radianes (Angle Punto_Inicio Punto_Fin))
              (Setq Angulo_Grados (/ (* Angulo_Radianes 180) PI))
 
              (Setq Angulo_Grados2 (+ Angulo_Grados 90))
 
              (Command "osnap" "NEA")
	      (setq Pto_1 (getpoint "\nPrimer punto: ")) (terpri)
              (Setq Pto_mid (Polar Pto_1 (/ (* Angulo_Grados2 PI) 180.0) Distancia_Texto_Linea))
              (If (And  (>= Angulo_Grados 90) (<= Angulo_Grados 270) )
                (Progn
                    (Setq Angulo_Radianes (Angle Punto_Fin Punto_Inicio))
                    (Setq Angulo_Grados (/ (* Angulo_Radianes 180) PI))
                )
              )
              (setq Vano_electrico1 (getstring "INGRESA VANO ELECTRICO 1 : "))(TERPRI)
              (Command "text" "s" Estilo "j" Justificacion Pto_mid Altura_Texto Angulo_Grados Vano_electrico1 )
              (Command "Chprop" "Last" "" "LA" Layer_Texto "" )
 
 
	      (setq Pto_2 (getpoint "\nSegundo Vano: ")) (terpri)
              (Setq Pto_mid2 (Polar Pto_2 (/ (* Angulo_Grados2 PI) 180.0) Distancia_Texto_Linea))
              (If (And  (>= Angulo_Grados 90) (<= Angulo_Grados 270) )
                (Progn
                    (Setq Angulo_Radianes (Angle Punto_Fin Punto_Inicio))
                    (Setq Angulo_Grados (/ (* Angulo_Radianes 180) PI))
                )
              )
 
 
              (setq Vano_electrico2 (getstring "INGRESA MEDIO AMERICANO 2 : "))(TERPRI)
              (Command "text" "s" Estilo "j" Justificacion Pto_mid2 Altura_Texto Angulo_Grados Vano_electrico2 )
              (Command "Chprop" "Last" "" "LA" Layer_Texto "")
 
 
)
 
        )
    )
  (Print)
  )

atento a vuestras consultas
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

rutina con error

Publicado por Gerardo (987 intervenciones) el 02/04/2020 23:23:02
Hola
No he podido probarla, pero si estás seguro de que la semántica es correcta, prueba a agregar un _none antes de indicar el punto de inserción de textos

1
(Command "text" "s" Estilo "j" Justificacion "_non" Pto_mid Altura_Texto Angulo_Grados Vano_electrico1 )

Me parece que cuando llegas a este punto tienes el osnap en modo "nearest" entonces si el zoom se acerca lo suficiente a la polilinea captura ese modo magnético cuando le pasas el punto de insercion al comando text.
Con el "none" se ignora el osnap para ese punto

Es un problema de las rutinas que trabajan con command, son demasiado dependientes del estado de la interfaz
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

rutina con eror

Publicado por JORGE VERGARA C (6 intervenciones) el 07/04/2020 20:56:24
Hola :
Probé cambiando el osnap en modo "nearest" en "none" y resulta como debiera, pero al cargar la rutina arroja este error

Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.
Command:

que significa y como puedo remediarlo.


atento a vuestros comentarios
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

rutina con error

Publicado por Gerardo (987 intervenciones) el 07/04/2020 23:46:09
Hola

Cuando se genera un error el autocad dispara una función interna llamada *error*
por defecto lo único que hace esa función es indicar de que error se trata, pero uno la puede sobreescribir. Por ejemplo para que si has cambiado los osnaps u otras variables esta función de error antes de imprimir el mensaje de error devuelva esas variables a los valores que tenian antes de la rutina.

Tu rutina al cargarse está generando un error (ojo, es diferente uno al cargar que uno al ejecutar), pero demasiados procesos son considerados como error. Por ejemplo, cualquier uso de la tecla "escape" durante la ejecución de un comando es un disparador de error. (Los comandos deben cancelarse con intro, no con escape)

Cual es el problema aquí? que en esa rutina que posteaste no tiene una función *error* y la original de autocad no tiene llamadas a comandos. Quiere decir que la función de error la está generando otra rutina que tienes cargada. Y que además está fallando porque no devuelve el control a la funcion *error* original de Autocad

Tendrás que buscar entre otros lisps que estés cargando cual tiene una redefinición de *error* que esté quedando cargada
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

rutina con error

Publicado por Gerardo (987 intervenciones) el 08/04/2020 16:44:26
Tema aparte
Intenta resumir tu código, para verlo más claro.

Puedes cambiar el (limpia) por (command), el (command osnap ) por (setvar osmode)
(And (>= Angulo_Grados 90) (<= Angulo_Grados 270) ) se puede escribir (<= 90 Angulo_Grados 270), y ese mismo if la segunda vez es innecesario, porque si el angulo de la polilínea no cambia, la rotación del primer texto será necesariamente la misma del segundo texto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(Defun C:L2 nil
 
	(Setq	Layer_Linea		"Linea_electrica"
			Color_Linea		7
			Layer_Texto		"Linea_electrica"
			Color_Texto		7
			Altura_Texto	1.5
			Estilo			"ROMANS"
			Justificacion	"Middle"
			Distancia_Texto_Linea	1.0
	)
	(Command "layer" "n" Layer_Linea "c" Color_Linea Layer_Linea
				"n" Layer_Texto "c" Color_Texto Layer_Texto ""
	)
	(command)
	(setvar "osmode" 64)
	(if (Setq Punto_Inicio (Getpoint "Seleccione Primer Punto Inicio :"))
		(Progn
			(Setq Punto_Fin (Getpoint Punto_Inicio "Seleccione Segundo Punto Fin :"))
			(Command "Pline" Punto_Inicio Punto_Fin "" "Chprop" "Last" "" "LA" Layer_Linea "")
			(command)
			(Setq Distancia			(Distance Punto_Inicio Punto_Fin)
					Valor_Texto		Distancia
					Angulo_Radianes	(Angle Punto_Inicio Punto_Fin)
					Angulo_Grados		(/ (* Angulo_Radianes 180) PI)
					Angulo_Grados2		(+ Angulo_Grados 90)
			)
			(setvar "osmode" 512)
	      (setq Pto_1		(getpoint "\nPrimer punto: ")
					Pto_mid	(Polar Pto_1 (/ (* Angulo_Grados2 PI) 180.0) Distancia_Texto_Linea)
			)
			(If	(<= 90 Angulo_Grados 270)
				(Setq Angulo_Radianes	(Angle Punto_Fin Punto_Inicio)
						Angulo_Grados		(/ (* Angulo_Radianes 180) PI)
				)
			)
			(setq Vano_electrico1	(getstring "INGRESA VANO ELECTRICO 1 : "))
			(Command "text" "s" Estilo "j" Justificacion Pto_mid Altura_Texto Angulo_Grados Vano_electrico1
						"Chprop" "Last" "" "LA" Layer_Texto ""
			)
			(setq Pto_2		(getpoint "\nSegundo Vano: ")
					Pto_mid2	(Polar Pto_2 (/ (* Angulo_Grados2 PI) 180.0) Distancia_Texto_Linea)
					Vano_electrico2 (getstring "INGRESA MEDIO AMERICANO 2 : ")
			)
			(Command "text" "s" Estilo "j" Justificacion Pto_mid2 Altura_Texto Angulo_Grados Vano_electrico2
						"Chprop" "Last" "" "LA" Layer_Texto ""
			)
		)
	)
	(Princ)
)

Otra opción es que veas en la ayuda como trabaja la función entmake, que usa listas dxf para crear objetos y entidades. Y entonces ya no uses más ninguna sentencia coomand, sino que todo lo crees con entmake (o lo modifiques con entmod). Entre las ventajas de hacerlo así es que habrá menos errores, que será más limpio y se ejecutará más rapido, y que tienes un solo comando: si hacemos undo (deshacer) a tu rutina irá deshaciendo cada command uno por uno, mientras que si lo haces con una que no tiene commands como la que te voy a adjuntar a continuación se deshará el comando L2 de una sola vez
Aquí tienes tu misma rutina quitando todos los commands:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(Defun C:L2 (/ pt_ini pt_fin dist ang a+90 osmv pt ptmid text angtxt)
;Si no existe la capa crearla
	(if (null (tblsearch "LAYER" "Linea electrica"))
		(entmake '(	(0 . "LAYER")
						(100 . "AcDbSymbolTableRecord")
						(100 . "AcDbLayerTableRecord")
						(2 . "Linea electrica")
						(62 . 7)
						(6 . "CONTINUOUS")
						(70 . 1)
						(290 . 1)
					)
		)
	)
;Si no existe el estilo crearlo
	(if (null (tblsearch "STYLE" "ROMANS"))
		(entmake '(	(0 . "STYLE")
						(100 . "AcDbSymbolTableRecord")
						(100 . "AcDbTextStyleTableRecord")
						(2 . "ROMANS")
						(70 . 0)
						(40 . 0)
						(41 . 1)
						(50 . 0)
						(71 . 0)
						(3 . "romans.shx")
					)
		)
	)
;cuerpo principal
	(if	(and
				(setq pt_ini (getpoint "\nSeleccione Primer Punto (inicio):"))
				(setq pt_fin (getpoint pt_ini "\nSeleccione Segundo Punto (fin):"))
			)
		(progn
			(entmake
				(list	'(0 . "LWPOLYLINE")
						'(100 . "AcDbEntity")
						'(100 . "AcDbPolyline")
						'(8 . "Linea electrica")
						'(6 . "ByLayer")
						'(62 . 256)
						'(90 . 2)
						'(70 . 0)
						(cons 10 pt_ini)
						(cons 10 pt_fin)
				)
			)
			(setq dist	(distance pt_ini pt_fin)
					ang	(angle pt_ini pt_fin)
					a+90	(rem (+ ang (* pi 0.5)) pi)
					osmv	(getvar "osmode")
			)
			(setvar "osmode" 512)
			(setq pt		(getpoint "\nPrimer punto: ")
					ptmid	(polar pt a+90 1.0)
					text	(getstring "\nIngresa vano eléctrico 1: ")
					angtxt	(+ ang (if (<= (* pi 0.5) ang (* pi 1.5)) pi 0.))
			)
			(entmake (list	'(0 . "TEXT")
								(cons 1 text)
								'(7 . "ROMANS")
								'(8 . "Linea electrica")
								'(10 0. 0. 0.)
								(cons 11 ptmid)
								'(40 . 1.5)
								(cons 50 angtxt)
								'(72 . 1)
								'(73 . 2)
						)
			)
			(setq pt		(getpoint "\nSegundo vano: ")
					ptmid	(polar pt a+90 1.0)
					text	(getstring "Ingresa medio americano: ")
			)
			(entmake (list	'(0 . "TEXT")
								(cons 1 text)
								'(7 . "ROMANS")
								'(8 . "Linea electrica")
								'(10 0. 0. 0.)
								(cons 11 ptmid)
								'(40 . 1.5)
								(cons 50 angtxt)
								'(72 . 1)
								'(73 . 2)
						)
			)
			(setvar "osmode" osmv)
		)
	)
	(princ)
)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

rutina con error

Publicado por JORGE VERGARA C (6 intervenciones) el 28/04/2020 18:12:50
muchas gracias tengo una visión distinta para generar código, desconocía esta forma de programar, desde ya muy agradecido, aunque al ejecutarlo note que los elementos que dibujaba no aparecían, al revisar note que (70.1) me deja el layer congelado, al ir probando en hoja en blanco pude deducir que (70.1) crea el layer de manera visible, me podrían facilitar las demás opciones de capa que existen para tenerlos presentes en proyectos futuros, de antemano muchas gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

rutina con error

Publicado por Gerardo (987 intervenciones) el 29/04/2020 08:01:05
Hola

Pues mira todo y quédate con lo que te sirva. Cada quien tiene su forma de sacarse pulgas.
Programar con códigos dxf en vez de comandos pues ser un alivio en manejo de errores y velocidad, pero un poco más tedioso y menos intuitivo para generar el código de creación del objeto. Solo que si lo haces con command deberás pensar más en control de errores, manejo de variables, agrupación para "deshacer", versión de autocad (porque hay comandos que cambian entre versiones) y tiempo de ejecución en caso de repeticiones abundantes.

Lo que pasa también es que si aplicas los criterios de división de tareas y reutilización, solo hay que crear una función que dibuje líneas, entonces puedes concentrarte en hacer la mejor función que dibuje líneas, porque luego cada vez que dibujes una linea solo invocarás tu función. Por ejemplo, si creamos esta función de servicio

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(defun gc:traza_circulo (centro radio layer color ltype ltscale )
	(entmake
		(list
			'(0 . "CIRCLE")
			'(100 . "AcDbEntity")
			'(410 . "Model")
			(cons 8 (if layer layer (getvar "CLAYER")))
			(cons 62 (if color color (atoi (getvar "CECOLOR"))))
			(cons 6 (if ltype ltype (getvar "CELTYPE")))
			(cons 48 (if ltscale ltscale (getvar "CELTSCALE")))
			(cons 10 centro)
			(cons 40 radio)
			'(210 0.0 0.0 1.0)
		)
	)
)


Después, cada vez que ocupes dibujar un círculo solo hay que hacer llamadas como estas

1
(gc:traza_circulo Centro1 1.25 "Micapa" 3 "Hidden" 1.0)

1
(gc:traza_circulo '(12.0 15.5) 1.7 nil nil nil nil)

Para encontrar todos los códigos DXF pues buscas en la ayuda el tipo de objeto. Por ejemplo para capas ponemos Layer (dxf) y sale lo siguiente:
https://help.autodesk.com/view/ACD/2020/ENU/?guid=GUID-D94802B0-8BE8-4AC9-8054-17197688AFDB
ahí se puede apreciar para el código 290 lo que descubriste. Si el código 70 vale 1 está congelada, hay que poner (70 . 0) para que salga descongelada. Un 4 [ (70 . 4) ] la crea bloqueada. Y la suma de ambos --> (70 . 5) la crearía congelada y bloqueada. Colocar el número del color como valor negativo la crearía apagada (ej (62 . -5) una capa azul apagada)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar