mikarts Posted June 5 Posted June 5 (edited) Buenas tardes y gracias por vuestra ayuda de antemano como siempre. Creo que esta rutina puede serle útil a bastante gente. Lo que pretendo es hacer unas copias consecutivas en un sentido (a la derecha, para hacer más sencilla la orden) de manera que entre copia y copia pida la distancia a copiar relativa desde el último punto extraído. Es decir, necesito que las x sean incrementales. La idea es hacer una orden con funcionamiento similar a la orden acocontinua, pero copiando objetos en vez de acotando, e introduciendo la coordenada x en vez de un punto. La tengo bastante definida, pero no consigo que cambie el punto de origen de la copia. A ver si alguien me puede indicar dónde cometo el error. Gracias: (defun c:kl (/ ents n xi ptoi ptof) (princ "\nSeleccione los objetos a copiar a derecha: ") (setq ents (SSGET)) (setq n 1) (setq ptoi (list 0 0)) (setq xi 0) (while n (setq xi (+ xi (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha:")))) (setq ptof (list xi 0)) (command "_copy" ents "" ptoi ptof "") ; hasta aquí creo que va todo bien. (setq ptoi ptof) ; no funciona, me mantiene el 0,0 como ptoi. ) ) Edited June 5 by mikarts Mistakes Quote
GLAVCVS Posted June 5 Posted June 5 (edited) Hi No: ptoi is fine The problem is that you're constantly copying the selected set of objects to the beginning. You need to find a way to update the selection. Or, effectively, keep ptoi at 0.0. Edited June 5 by GLAVCVS Quote
mikarts Posted June 5 Author Posted June 5 26 minutes ago, GLAVCVS said: Hi No: ptoi is fine I think, the problem is that you're constantly copying the set of selected objects to the beginning. You need to find a way to update the selection. Ah! You're right. But I'm going to try keeping the ptoi at 0,0 and only changing ptof. It should work... Quote
mikarts Posted June 5 Author Posted June 5 Done! Thank you so much! Here is the right code: (defun c:kl (/ ents n xi ptof) (princ "\nSeleccione los objetos a copiar a derecha: ") (setq ents (SSGET)) (setq n 1) (setq xi 0) (while n (setq xi (+ xi (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha:")))) (setq ptof (list xi 0)) (command "_copy" ents "" "0,0" ptof "") ) ) Quote
Isaac26a Posted June 5 Posted June 5 Just some comments hope they are useful to you (defun c:kl (/ ents n ole olo xi ptof) (command "_.undo" "_begin") (setq olo (getvar "osmode")) ;;; Se guarda la configuracion de Osnap actual (setq ole (getvar "cmdecho")) ;;; Se guarda la configuracion actual (setvar "osmode" 0) ;;; Se cambia a No osnap para que no te genere errores en distancias al copiar (setvar "cmdecho" 0) ;;; Para evitar que te salgan mensajes que no son necesarios ver (setq xi 0) (princ "\nSeleccione los objetos a copiar a la derecha: ") (setq ents (SSGET)) (while (setq n (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha:"))) (setq xi (+ xi n)) (setq ptof (list xi 0)) (command "_.copy" ents "" "0,0" ptof "") ) (command "_.undo" "_end") ;;; Te permite deshacer lo que hiciste si quieres regresar a como era tu dibujo (setvar "osmode" olo) ;;; Restauras la configuracion de Osnap (setvar "cmdecho" ole) ;;; Se restaura la configuracion (princ) ;;; Te permite una salida limpia sin mostrar funciones o procesos ) And remember this is a English speaking site even if there are many people speaking other languajes Quote
BIGAL Posted June 5 Posted June 5 Once you draw all the lines look at using QDIM. Will dimension all lines in one go. Quote
mikarts Posted June 6 Author Posted June 6 9 hours ago, Isaac26a said: Just some comments hope they are useful to you (defun c:kl (/ ents n ole olo xi ptof) (command "_.undo" "_begin") (setq olo (getvar "osmode")) ;;; Se guarda la configuracion de Osnap actual (setq ole (getvar "cmdecho")) ;;; Se guarda la configuracion actual (setvar "osmode" 0) ;;; Se cambia a No osnap para que no te genere errores en distancias al copiar (setvar "cmdecho" 0) ;;; Para evitar que te salgan mensajes que no son necesarios ver (setq xi 0) (princ "\nSeleccione los objetos a copiar a la derecha: ") (setq ents (SSGET)) (while (setq n (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha:"))) (setq xi (+ xi n)) (setq ptof (list xi 0)) (command "_.copy" ents "" "0,0" ptof "") ) (command "_.undo" "_end") ;;; Te permite deshacer lo que hiciste si quieres regresar a como era tu dibujo (setvar "osmode" olo) ;;; Restauras la configuracion de Osnap (setvar "cmdecho" ole) ;;; Se restaura la configuracion (princ) ;;; Te permite una salida limpia sin mostrar funciones o procesos ) And remember this is a English speaking site even if there are many people speaking other languajes Thank you. My next step was exactly that. You saved my time. Sorry for using Spanish I didn't know that. I'll try to speak only in my (awfull) English. Quote
mikarts Posted June 6 Author Posted June 6 (edited) In sample I shown the dimensions step by step intentionally. But BIGAL you gave a good idea. We can try to implement that. Please let's think together how to do it: To implement that I think that we'll need to make a new selection set, adding the new entities at any time. For only one entity, as shown in sample, it should be easy to do with entlast. But the command works also with more than one ent (ssget and not entget). I'd like to keep this option. Therefore we'll need to detect how many entities there are in ents (I don't know how to do that). Once we have done that we have two ways: 1.- If it is only 1, to make the new selection set and to do the QDIM command. 2.- If there are more that one entity, not to do anything more. But we have another issue: the command will work till you press the esc key. But if you do that you can't use QDIM anymore inside the command... Too complicated, isn't it? Maybe is an easier way to get the starting point at the first entity and to dimension directly in any iteration. But if we try that, the trouble will be that there are many entities without starting point, like circles or blocks, isn't it? Then, is it any common point to all kind of entities like an insert point or similar? If it exists can we get it from the list of the object? Edited June 6 by mikarts Added Bigal Quote
mikarts Posted June 6 Author Posted June 6 (edited) @Isaac26a I noticed that your functions doesn't work by pressing the esc key because it are outside from the while. In the next code I've put your lines inside the while. The only working difference is the undo command, but I think that is better to have the capability of undoing any iteration of copy and dimension. @BIGAL Dimensions implemented in any iteration. Next step that I wish to implement: keeping the distance introduced by user and offer it in the next copy. Here the new code: (defun c:kl (/ ents ptoc ptoi xi yi yc olo n ole ptof) (princ "\nSeleccione los objetos a copiar a la derecha:") (setq ents (SSGET)) (setq ptoc (getpoint "\nIntroduzca el punto desde donde acotar:")) (setq ptoi ptoc) (setq xi (car ptoc)) (setq yi (cadr ptoc)) (setq yc (- yi 1)) (setq olo (getvar "osmode")) ;;; Se guarda la configuración de Osnap actual (setq ole (getvar "cmdecho")) ;;; Se guarda la configuración actual (while (setq n (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha:"))) (command "_.undo" "_begin") (setvar "osmode" 0) ;;; Se cambia a No osnap para que no te genere errores en distancias al copiar (setvar "cmdecho" 0) ;;; Para evitar que te salgan mensajes que no son necesarios ver (setq xi (+ xi n)) (setq ptof (list xi yi)) (command "_.copy" ents "" ptoi ptof "") (command "_dimlinear" ptoc ptof (list 0 yc)) (setq ptoc ptof) (setvar "osmode" olo) ;;; Restauras la configuración de Osnap (setvar "cmdecho" ole) ;;; Se restaura la configuración (command "_.undo" "_end") ;;; Te permite deshacer lo que hiciste si quieres regresar a como era tu dibujo (princ) ;;; Te permite una salida limpia sin mostrar funciones o procesos ) ) Edited June 6 by mikarts Better code Quote
mikarts Posted June 6 Author Posted June 6 I got it. This is the code. I think that it does all I wanted. I'll wait for any idea for improving the command. Thank you very much to anyone. (defun c:kl (/ ents ptoc ptoi xi yi yc olo ole tmp ptof) (princ "\nSeleccione los objetos a copiar a la derecha:") (setq ents (SSGET)) (setq ptoc (getpoint "\nIntroduzca el punto desde donde acotar:")) (setq ptoi ptoc) (setq xi (car ptoc)) (setq yi (cadr ptoc)) (setq yc (- yi 1)) (setq olo (getvar "osmode")) (setq ole (getvar "cmdecho")) (if (null distancia) (setq distancia 1)) (while (setq distanciastr (rtos distancia)) (if (setq tmp (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha <" distanciastr ">:"))) (setq distancia tmp)) (command "_.undo" "_begin") (setvar "osmode" 0) ;;; Se cambia a No osnap para que no te genere errores en distancias al copiar (setvar "cmdecho" 0) ;;; Para evitar que te salgan mensajes que no son necesarios ver (setq xi (+ xi distancia)) (setq ptof (list xi yi)) (command "_.copy" ents "" ptoi ptof "") (command "_dimlinear" ptoc ptof (list 0 yc)) (setq ptoc ptof) (setvar "osmode" olo) ;;; Restauras la configuración de Osnap (setvar "cmdecho" ole) ;;; Se restaura la configuración (command "_.undo" "_end") ;;; Te permite deshacer lo que hiciste si quieres regresar a como era tu dibujo (princ) ;;; Te permite una salida limpia sin mostrar funciones o procesos ) ) Quote
mikarts Posted June 10 Author Posted June 10 Hello again. I'm looping the loop with this command. Now I wish to allow user input for undoing or exiting. I have detected some issues which I need your help: 1.- distanciastr has disappeared from cursor point and doesn't work anymore by pressing enter. I can't solve it. 2.- when undo, the point for the new copy doesn't come back. Should I keep ptoi and ptof in both lists and call back them with any undo? Thanks to everyone. (defun c:kll (/ ents ptoc ptoi xi yi yc olo ole opt ptof) (princ "\nSeleccione los objetos a copiar a la derecha:") (setq ents (SSGET)) (setq ptoc (getpoint "\nIntroduzca el punto desde donde acotar:")) (setq ptoi ptoc) (setq xi (car ptoc)) (setq yi (cadr ptoc)) (setq yc (- yi 1)) (setq olo (getvar "osmode")) (setq ole (getvar "cmdecho")) (if (null distancia) (setq distancia 1)) (while (setq distanciastr (rtos distancia)) (setvar "osmode" 0) ;;; Se cambia a No osnap para que no te genere errores en distancias al copiar (setvar "cmdecho" 0) ;;; Para evitar que te salgan mensajes que no son necesarios ver (initget 130 "desHacer Salir") ;;;2 (evita 0) + 128 (permite input arbitrario tras bits de control y palabras clave listadas. (setq opt (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha o [desHacer/Salir] <" distanciastr ">: "))) (cond ((eq opt "desHacer") (command "_undo" "_back")) ((eq opt "Salir") (exit)) ((numberp opt) (progn (command "_.undo" "_mark") (setq distancia opt) (setq xi (+ xi distancia)) (setq ptof (list xi yi)) (command "_.copy" ents "" ptoi ptof "") (command "_dimlinear" ptoc ptof (list 0 yc)) (setq ptoc ptof) (setvar "osmode" olo) ;;; Restauras la configuración de Osnap (setvar "cmdecho" ole) ;;; Se restaura la configuración (princ) ;;; Te permite una salida limpia sin mostrar funciones o procesos ) ) ) ) ) Quote
mikarts Posted June 19 Author Posted June 19 Hi again. As no one has answered I wonder if I should open a new thread. Anyway, I have solved the undo problem. (And also osmode and exit minor issues.) The first problem with distanciastr remains. Here is the newest code. Any help or suggestion is well received. Thank you. (defun c:kll (/ ents ptoc ptoi xi yi yc olo ole opt ptof distanciastr copia-historial cota-historial xi-historial salida-normal) ;; Función personalizada para manejar errores (defun *error* (msg) (if (not salida-normal) ; Si la salida no fue normal (ESC o error inesperado) (progn (setvar "osmode" olo) ; Restaura osmode (setvar "cmdecho" ole) ; Restaura cmdecho (princ "\nOperación cancelada.") ; Evita el mensaje de error ) ) (princ) ) ;; Inicio de la orden (princ "\nSeleccione los objetos a copiar a la derecha:") (setq ents (ssget)) (setq ptoc (getpoint "\nIntroduzca el punto desde donde acotar:")) (setq ptoi ptoc) (setq xi (car ptoc)) ; Guarda la coordenada X inicial (setq yi (cadr ptoc)) ; Guarda la coordenada Y inicial (setq yc (- yi 1)) ; Define la coordenada Y para las cotas (setq olo (getvar "osmode")) (setq ole (getvar "cmdecho")) (if (null distancia) (setq distancia 1)) (setq distanciastr (rtos distancia)) ; Asegura que distanciastr esté bien definida ;; Inicio de los historiales (setq copia-historial '()) ; Lista para almacenar los puntos de las copias (setq cota-historial '()) ; Lista para almacenar los puntos de las cotas (setq xi-historial '()) ; Lista para almacenar los valores de xi (setq salida-normal nil) ; Variable de control para saber si la salida fue normal ;; Bucle principal (while (/= opt "Salir") ; Mientras que no se elija la opción "Salir" hace esto. (initget 130 "desHacer Salir") ; Mostrar las opciones (setq opt (getreal (strcat "\nIntroduzca distancia a copiar hacia la derecha o [desHacer/Salir] <" distanciastr ">: "))) (cond ((eq opt "desHacer") (progn (if (not (null copia-historial)) ; Solo deshacer si hay algo en el historial (progn ;; Deshacer la última copia, cota y xi (setq ptof (car copia-historial)) ; Recupera el último punto de la copia (setq ptoc (car cota-historial)) ; Recupera el último punto de la cota (setq xi (car xi-historial)) ; Recupera el último valor de xi (command "_undo" "_back") ;; Elimina los valores deshechos del historial (setq copia-historial (cdr copia-historial)) (setq cota-historial (cdr cota-historial)) (setq xi-historial (cdr xi-historial)) (princ "\nÚltima copia deshecha.") ) (princ "\nNo hay nada que deshacer. Para deshacer más salga de la orden y utilice el comando deshacer.") ) ) ) ; Fin de opción "desHacer" ((eq opt "Salir") (progn ;; Restaura osmode y cmdecho antes de salir (setq salida-normal t) ; Marca que la salida fue normal (setvar "osmode" olo) (setvar "cmdecho" ole) (princ "\nSe ha elegido Salir. Fin de comando.") ) ) ; Fin de opción "Salir" ((numberp opt) ; Si la opción es un número, realiza la copia (progn (command "_.undo" "_mark") ; Marca el punto de deshacer (setvar "osmode" 0) ; Cambiar a No osnap (setvar "cmdecho" 0) ; Desactivar el eco de comandos (setq xi-historial (cons xi xi-historial)) ; Guarda el valor de xi en el historial antes de modificarlo (setq distancia opt) ; Asigna la nueva distancia (setq xi (+ xi distancia)) ; Calcula la nueva coordenada X (setq ptof (list xi yi)) ; Establece el punto de destino de la copia (command "_.copy" ents "" ptoi ptof "") (command "_dimlinear" ptoc ptof (list 0 yc)) (setq copia-historial (cons ptof copia-historial)) ; Agrega al historial de copias (setq cota-historial (cons ptoc cota-historial)) ; Agrega al historial de cotas (setq ptoc ptof) ; Actualiza el punto de acotación (setvar "osmode" olo) ; Restaura el valor de osnap (setvar "cmdecho" ole) ; Restaura el valor de cmdecho (princ) ; Limpia la salida ) ) ) ) (princ) ) Quote
GLAVCVS Posted June 19 Posted June 19 Hi From my smartphone I can only see 'distanciastr' once in the code. But it's assigned the value returned by 'rtos' applied to an integer: 'rtos' should be used with real numbers. To convert an integer to a text string, use 'itoa'. Quote
GLAVCVS Posted June 19 Posted June 19 (edited) Now from my PC. Although using rtos to convert an integer doesn't seem to be the problem, I think it's a good idea to use the appropriate functions in each case. Regarding your issues, two notes: -Your code refers, at the start, to the variable opt, which in turn depends on the value stored in the variable distancia. If this already has a value, pressing ENTER or Right Click should cause opt to take the value of distancia. But it doesn’t, because there's no code to do so. For this reason, when the command starts and suggests the user to repeat the last distance, the command doesn't work because opt is nil. I see you're using AI to help develop the code, so I suggest you explain this situation to it, and I believe it will provide a solution. If not, come back and ask again. -In '(command "_dimlinear"... ', I think you should remove the final "" so that it runs cleanly. Edited June 19 by GLAVCVS Quote
mikarts Posted June 19 Author Posted June 19 Thank you @GLAVCVS. As I didn't received any answer and after looking a lot in the internet, efectively I used the IA for solving the undo trouble. It taked me a couple of hours reaching the code above with the IA aid. How have you guessed it? I have not worked yet with the distancia. In fact, I wasn't worried a lot about if the AI changed anything in that part of the code. It was a problem to solve later. I'm going to work with your suggestions from one of the first codes, when distancia worked properly and I'll come back. Thank you again. Quote
mikarts Posted June 19 Author Posted June 19 Hi again. I have reached to offer the previous distancia (with the AI aid) in command line and also in the cursor. I needed changing getreal for getstring and making several cond to choose between: - number - h or deshacer - s or salir - Enter - any other user input. But it still remains a little problem that I can't solve, neither with the AI help: the options in brackets only appears in commandline. Is any way to offer the options also in the cursor? I attach a picture where command line and cursor are shown. Here is the specific part of the code: (setq distanciastr (rtos distancia 2 2)) (setq tmp (getstring T (strcat "\nIntroduzca distancia a copiar hacia la derecha o [desHacer/Salir] <" distanciastr ">: "))) (PS: I'm enjoying a lot learning with this. Thank you everybody.) Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.