AutoCad - Ayuda con rutina autolisp de resta de regiones

 
Vista:
sin imagen de perfil
Val: 13
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

Ayuda con rutina autolisp de resta de regiones

Publicado por Antonio (15 intervenciones) el 20/05/2023 23:49:45
Buenas noches:

El otro día pedí ayuda por aquí y me respondió Gerardo, ayudándome con una pequeña rutina.

Pensé que a partir de esa ayuda, me seria muy fácil hacer la rutina siguiente:

Rutina que:

-en la primera entrada pida en contorno de la pieza.. (ese contorno ó panel siempre tiene que ser una
polilinea cerrada, y solo será una entidad ya que después se convierte en region y finalmente, cuando
se complete con la resta de las regiones hueco se acabara extruyendo....)

-En la segunda peticion de seleccion nos pide los huecos a restar de la primera region, y nos los pide
seleccionar mediante SSGET, (para poder seleccionarlo uno a
uno... mediante una ventana o como queramos (pero siempre va a ser un conjunto de selección, ya que serán varias entidades (Huecos). Estas entidades solo pueden ser Polilineas o Circulos, ya que luego las tiene que convertir también a Regiones (Para luego poder restarlas de la polilinea primera, convertida a region).

Hasta aquí esta conseguido, con la ayuda de Gerardo. Lo complicado para mi viene después y es que soy muy torpe y no se programar....

Necesito que los huecos de la segunda selección se resten de la primera
Y que me devuelva una sola region... en la que estén restados los huecos...

Con la ayuda de Gerardo ya he consigo que me pida los objetos...

Pienso que necesito un bucle en el que se vayan restando una por una las entidades de la segunda selección (los llamados huecos)....
Pero no se implementarlo. Alguien me puede ayudar?

Adjunto lo que tengo escrito de programa hasta ahora y un dibujo DWG de ejemplo...

Muchas gracias por vuestra ayuda

(defun c:RestaRegiones2 ( / i contorno L nhuecos contorno1)


(princ "\nSeleccione el contorno del panel:")

(setq
;selección con filtro para incluir solo polilíneas cerradas


contorno (ssget "_:S" '((0 . "LWPOLYLINE")(-4 . "&") (70 . 1)))


) ;parentesis fin del primer setq


(command "_Region" contorno "")

(setq contorno1 (entlast))

(princ "\nSeleccione los huecos a restar:")

(setq
;contador para luego iterar por el selection set
i 0
;selección con filtro para incluir solo polilíneas cerradas y circulos


nhuecos (ssget '((-4 . "<OR")
(-4 . "<AND")(0 . "LWPOLYLINE")(-4 . "&") (70 . 1) (-4 . "AND>")
(-4 . "<AND")(0 . "CIRCLE")(-4 . "AND>")
(-4 . "OR>")
))


) ;parentesis fin del primer setq


;bucle que itera por el selection set agregando las entidades a la lista L


(repeat (sslength nhuecos)

(setq L (cons (vlax-ename->vla-object (ssname nhuecos i))
L
))
i (1+ i)
)


(command "_Region" nhuecos "")



(command "_.subtract" contorno1 "" huecos "")


) ; fin del DEFUN
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

Ayuda con rutina autolisp de resta de regiones

Publicado por Gerardo (986 intervenciones) el 27/05/2023 04:55:22
bien amigo. Lo siguiente va más con carácter didáctico que de solución.
Primero un poco de mteria y luego el código.

Esto para que quede claro a ti y a cualquier otro interesado:

Hay 3 tipos de programación en autolisp para modificar dibujos. 1-Por comandos de autocad, 2-por base de datos (dxf) y 3-Por objetos activeX.

La primera consiste en enviar comandos, es la más sencilla, aunque la más limitada y a veces más propensa a errores. Recomendada para cosas o muy sencillas de trámite rápido o muy complejas (como restar regiones jeje) para delegarle al autocad parte
Ejemplo:
1
(command "Line" pt1 pt2 "")

La segunda es la más natural del autolisp (y mi preferida), trabaja las entidades como apuntadores a las posiciones de memoria donde están y consiste en escribir o reescribir la base de datos del dibujo.
Ejemplo
1
(entmake  (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt2)))

La tercera es más "microsoft" aprovechando la tecnología ActiveX, más familiar para los que trabajan con lenguajes convencionales como vbasic, pero suele requerir de transformar entidades en objetos vlax para manipularlos
Ejemplo:
1
(vla-AddLine ModelSpace (vlax-3d-point pt1) (vlax-3d-point pt2))

El tema es que, aunque a muchas veces se requiere combinar estos tipos de programación, esa combinación complica los programas, en parte porque el tipo de datos es diferente, al menos entre el modo 2 y 3, el manejo de excepciones es totalmente distinto entre los 3 modos y cada uno tiene como un set particular de funciones autolisp/vlisp, entonces al mezclarlo debes abarcar mucho más el lenguaje.

Yo recomiendo particularmente para quien quiera aprender a programar sustancialmente, que se olvide de la primera, y salvo excepciones muy pequeñas nunca usemos command en las rutinas. Luego quedarse con una de las otras dos opciones y solo combinar con la otra lo necesario o inevitable.

Todo lo anterior me surgió porque en tu código hay mezclados el "command" y el vlax-ename->vla-object, entonces a continuación te ofrezco dos soluciones, como dije, más didácticas, una con comandos y otra con activeX
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 13
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

Ayuda con rutina autolisp de resta de regiones

Publicado por Antonio (15 intervenciones) el 04/06/2023 22:33:22
Muchas Gracias Gerardo.

Hasta lo de ahora he probado solo esta rutina, la que tienes que selecionar tu a mano las poli-lineas, tanto la exterior, comolos huecos interiores a restar y funciona prefectamente, pero me ha costado implementarla luego en el programa que yo estoy escribiendo.

He ido a votar y solo me ha dejado darte un 1.... no se como funnciona esto, he ido a darle para subir votos y me dice que ya he votado por este mensaje.

Muchas gracias por la tu ayuda, de 10 siempre,

Un saludo y 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

Ayuda con rutina autolisp de resta de regiones

Publicado por Gerardo (986 intervenciones) el 27/05/2023 04:59:50
aquí las dos funciones como para que las analices y veas el alcance de cada tipo de programación
Verás que en la segunda no te pregunto por los contornos internos a restar de la region, porque estoy aprovechando el mismo polígono externo para seleccionarlos. Eso sabes como cambiarlo en el ssget si prefieres que sea el usuario quien seleccione manualmente y se complicaría si el contorno externo tuviera lados curvos, porque por ahora solo hace un poligono de seleccion entre los vertices de la polilinea. Pero creo que para explicar esa posibilidad de autoselección interna funcionará así.

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
(defun c:test1 ( / contorno i nhuecos )
	(setq contorno	(ssget "_:S" '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))
	(command "_Region" contorno "")
	(setq contorno (entlast))
	(princ "\nSeleccione los huecos a restar:")
	(if
		(setq	i	0
				nhuecos	(ssget
							  '(	(-4 . "<OR")
										(-4 . "<AND")
											(0 . "LWPOLYLINE")
											(-4 . "&")
											(70 . 1)
										(-4 . "AND>")
										(0 . "CIRCLE")
									(-4 . "OR>")
								)
							)
		)
		(repeat (sslength nhuecos)
			(command 	"_Region" (ssname nhuecos i) "" "_.subtract" contorno "" (entlast) "")
			(setq	i		(1+ i))
		)
	)
)

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
(defun c:test2 ( / contorno pts nhuecos mspace rcontorn k rhuecos Lhuecos)
	;seleccionar polilínea cerrada
	(if	(setq	contorno	(ssget "_:S" '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))
		(progn
			;entidad contorno
			(setq contorno	(ssname contorno 0)
			;obtener lista de vertices del polígono
					pts	(mapcar
								'cdr
								(vl-remove-if
									'(lambda(A) (/= (car A) 10))
									(entget contorno)
								)
							)
			;utilizar los vértices para seleccionar los contornos internos por ventana de poligono
					nhuecos	(ssget
									"WP"
									pts
									'(	(-4 . "<OR")
											(-4 . "<AND")
												(0 . "LWPOLYLINE")
												(-4 . "&")
									 				(70 . 1)
											(-4 . "AND>")
											(0 . "CIRCLE")
										(-4 . "OR>")
									)
								)
			;obtener el espacio modelo
					mspace	(vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
			;convertir contorno a region
					rcontorn	(vlax-safearray-get-element
									(vlax-variant-value
										(vla-AddRegion
											mspace
											(vlax-make-variant
												(vlax-safearray-fill
													(vlax-make-safearray vlax-vbobject '(0 . 0))
													(list (vlax-ename->vla-object contorno))
												)
											)
										)
									)
									0
								)
			)
			;borrar el el polígono del contorno
			(entdel contorno)
			;si hay nhuecos hacer lista de contornos internos
			(if	nhuecos
				(progn
					(setq k 0 ;contador
						;	rhuecos (vlax-make-safearray vlax-vbobject (cons 0 (1- (sslength nhuecos)))) ;array
					)
					;llenar lista
					(repeat (sslength nhuecos)
						(setq Lhuecos	(cons (vlax-ename->vla-object (ssname nhuecos k)) Lhuecos)
								k	(1+ k)
						)
					)
					;convertir a regiones
					(setq rhuecos	(vla-AddRegion
											mspace
											(vlax-make-variant
												(vlax-safearray-fill
													(vlax-make-safearray vlax-vbobject (cons 0 (1- (sslength nhuecos))))
													Lhuecos
												)
											)
										)
					)
					;borrar objetos originales
					(mapcar 'vla-Delete Lhuecos)
					;sustraer cada region creada
					(mapcar
						'(lambda (A)
							(vla-Boolean rcontorn acSubtraction A)
						)
						(vlax-safearray->list (vlax-variant-value rhuecos))
					)
				)
			)
		)
	)
)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar