Administración de CAD

Este es un sitio dedicado a comentar sobre asuntos relacionados con el diseño CAD, BIM y diseño en general, así como sobre la administración de la información generada por estas herramientas.

Siéntanse libres de comentar las entradas y compartirnos sus experiencias y opiniones.

miércoles, 4 de mayo de 2011

Rutina para convertir textos en nodos

Fernando, del estado de México, nos comparte una necesidad que trataremos de resolver mediante la programación de una rutina de AutoLISP.

La necesidad es la siguiente:

Se cuenta con un archivo DWG con una serie de objetos de texto, los cuales están insertados en puntos específicos y su contenido representa el nivel de dicho punto. Sin embargo, la coordenada Z es igual a 0 en todas las instancias.

Lo que se requiere es hacer una rutina que permita seleccionar un objeto, y que al hacerlo se cree un nodo o punto en el punto de inserción del texto, pero en el nivel que se indica en este último.

Cómo lo vamos a resolver.

Primero haremos una rutina que nos resuelva la necesidad de forma manual, es decir, que cree el punto como lo requerimos, pero seleccionando objeto por objeto.

Posteriormente, en otro post, crearemos una rutina que haga un ciclo de la rutina primaria y seleccione todos los objetos que cumplan con el criterio especificado y genere los puntos en el archivo de forma automática.

Rutina 1: Crear un punto en el punto de inserción del texto, pero con el nivel que se especifica en este último.

Primero abrimos nuestro block de notas y comenzamos con la definición de nuestro comando. Vamos a guardar el archivo como TXT2NODO.LSP y definiremos el comando como TXT2NODO (Texto a nodo)


   (defun C:TXT2NODO ()

Vamos ahora a capturar en una variable el contenido del texto, el cual nos servirá para tener a la mano el nivel en Z donde deseamos que se cree nuestro punto:

   (setq TEXTONIVEL (car (entsel "\nSeleccione un objeto de texto: ")))

La función ENTSEL nos permite seleccionar una entidad única al hacer click en esta. La función CAR nos permite extraer el primer elemento de una lista, en este caso, el identificador de la entidad que seleccionamos previamente. Lo que hacemos en este punto es establecer esa entidad en una variable, en este caso TEXTONIVEL.

Ahora almacenaremos en una variable el contenido del texto que seleccionamos.

   (setq NIVELZ (cdr (assoc 1 (entget TEXTONIVEL))))

Aquí estamos usando varias funciones: ENTGET nos permite obtener los valores de definición de la entidad, en función de la base de datos del DXF. La función ASSOC nos permite obtener uno de los valores de dicho listado, en este caso, el valor 1 (uno) corresponde al par que representa el contenido de la entidad, en este caso un texto. La función CDR nos permite obtener el segundo valor de una lista, en este caso, el contenido del texto como tal.

Lo que hacemos es almacenar en la variable NIVELZ el contenido del texto seleccionado. Para nuestro caso, es la coordenada Z del punto que deseamos dibujar en el plano.

Ahora capturaremos el punto de inserción de la entidad, en este caso, texto:

   (setq COORDTXT (cdr (assoc 10 (entget TEXTONIVEL))))

Usamos las mismas funciones que en el caso anterior, solo que en esta ocasión, el código que estamos recuperando es el código 10, el cual representa el punto de inserción de la entidad. Lo almacenamos en la variable COORDTXT.

El valor resultante de esta función es una lista con las coordenadas X, Y y Z, algo similar a lo siguiente: (1666.1 1197.9 0.0) Donde 1666.1 es X, 1197.9 es Y y 0.0 es Z.

Ahora, definiremos las coordenadas finales del punto que insertaremos en el dibujo, en función del punto de inserción del texto y su contenido como Z.

   (setq COORDNODO (LIST (car COORDTXT)(cadr COORDTXT)(atof NIVELZ)))

Lo que hacemos en este paso es crear una lista, elemento fundamental de AutoLISP, con las coordenadas X, Y y Z. Para ello, usamos los dos primeros elementos de la lista que almacenamos en la variable COORDTXT

Para extraer el primer valor de esta (Coordenada X), usamos la función CAR, para extraer el segundo valor (Coordenada Y) usamos la función CADR, y para definir el tercer valor, usaremos la función ATOF, la cual convierte una cadena de caracteres en un valor real. Dicho en otras palabras, nosotros teníamos almacenado en la variable NIVELZ el texto que contenía la entidad de texto que seleccionamos. Lo que hacemos con la función ATOF es convertir ese texto a un número real, para que el sistema lo pueda considerar como tal.

Al final, en la variable COORDNODO tendremos una lista con los puntos X, Y y Z que necesitamos para dibujar el punto o nodo que deseamos.

Ahora solo resta dibujar el punto de forma automática usando los valores que almacenamos en la variable COORDNODO.

   (command "POINT" COORDNODO)

Aquí estamos ejecutando el comando POINT, especificando que el punto en donde se colocará el punto o nodo está almacenado en la variable COORDNODO.

Ya solo nos queda finalizar la rutina.

  (princ)
   )

La función PRINC imprime una expresión en la línea de comandos, en este caso, no estamos especificando ningún parámetro, por lo que únicamente se imprimirá un campo en blanco.

El último paréntesis cierra la función DEFUN y le indica al sistema que la función ha terminado.

Código Final

El código final de la rutina quedaría así:

   (defun C:TXT2NODO ()
    (setq TEXTONIVEL (car (entsel "\nSeleccione un objeto de texto: ")))
    (setq NIVELZ (cdr (assoc 1 (entget TEXTONIVEL))))
    (setq COORDTXT (cdr (assoc 10 (entget TEXTONIVEL))))
    (setq COORDNODO (LIST (car COORDTXT)(cadr COORDTXT)(atof NIVELZ)))
    (command "POINT" COORDNODO)
    (princ)
   )

Con esto tenemos una rutina totalmente funcional, que nos permitirá cumplir con la necesidad que plantea Fernando. Para activarla, habrá que cargar la aplicación con el comando APPLOAD de AutoCAD, y teclear en la línea de comandos TXT2NODO.

Sin embargo, si bien esta rutina puede funcionar, no tenemos ningún tipo de control. Es posible seleccionar cualquier tipo de instancia, lo que nos puede dar resultados inciertos o errores en la función. Además, ¿qué tal si tenemos miles de puntos que convertir?

En el siguiente post veremos como podemos mejorar la función para tener mayor control y funcionalidad.

Pueden expresar sus dudas en este mismo post, o a mi correo, natanvg@gmail.com

Saludos!

8 comentarios:

  1. Natán...

    Mil gracias por la solución, ahora solo me resta refinarlo para que se pueda seleccionar por grupo y así hacerlo mas versátil, pero eso ya me tocara a mi, si me atoro ya te estaré consultando ;), y si yo en algo te puedo ayudar estoy a tus ordenes :).

    Recibe un Cordial Saludos
    Atte. FerCar

    ResponderEliminar
  2. Hola Fernando...

    La intensión es continuar ayudándote, solo que por la carga que traemos ahorita, sería de forma gradual. Sin embargo, como bien mencionas, podrías ir probando con lo que te mando en lo que definimos el resto de la solución.

    Saludos!

    ResponderEliminar
  3. Hola Natan me quiero iniciar en el uso del software de autocad, quesiera me ayudaras como principiante

    ResponderEliminar
  4. Hola!!

    Aprovecha la oferta que está haciendo la Comunidad Latinoamericana de Usuarios de Autodesk en Español sobre cursos gratuitos de AutoCAD.

    Es muy sencillo, en el siguiente vínculo encontrarás mas información:

    http://communities.autodesk.com/?nd=news_detail&news_id=593&minisite_id=6

    ResponderEliminar
  5. Buenas Noches Natán.

    Lo prometido es deuda hay te dejo la rutina completa para quien le sea útil, ya con esta puedes seleccionar varios textos numéricos a la vez, saludos.

    ;----------------------------------------------------------------------------
    (defun inic ( / n nent lent)
    (Prompt "Selecionar Texto de Nivel a Marcar: ") (terpri)
    (while (not conj) (setq conj (ssget)))
    (setq num (sslength conj))
    (setq n 0)
    (repeat num
    (setq nent (ssname conj n))
    (setq lent (entget nent))
    (if (/= (cdr (assoc 0 lent)) "TEXT")
    (progn (ssdel nent conj) (setq n (- n 1)))
    )
    (setq n (+ n 1))
    )
    )
    (defun inspto ( / n TXTNIV NIVZ COORDTXT COORDNODO)
    (setq n 0)
    (repeat num
    (setq TXTNIV (ssname conj n))
    (setq NIVZ (cdr (assoc 1 (entget TXTNIV))))
    (setq COORDTXT (cdr (assoc 10 (entget TXTNIV))))
    (setq COORDNODO (LIST (car COORDTXT)(cadr COORDTXT)(atof NIVZ)))
    (command "POINT" COORDNODO)
    (setq n (+ 1 n))
    )
    )
    (defun C:T2N ( / ce om num conj)
    (setq ce (getvar "CMDECHO")
    om (getvar "OSMODE")
    )
    (setvar "CMDECHO" 0)
    (setvar "OSMODE" 0)
    (inic)
    (inspto)
    (setvar "CMDECHO" ce)
    (setvar "OSMODE" om)
    (princ)
    );Fin de funsión



    espero les sea de utilidad para aquellos que sus topógrafos les envian lo niveles en texto a elevación 0 (cero).

    Reciban un cordial saludo.

    Atte.
    FerCar

    ResponderEliminar
  6. Excelente!!

    La probaré a la primer oportunidad...

    En el futuro también me gustaría compartir mi versión.

    Muchas Gracias!

    ResponderEliminar
  7. que tal buen dia!, antes que nada mis felicitaciones a todos ustedes por desarrollar herramientas tan poderosas, y a la vez aprovecho para preguntar a anonimo como hago para poder hacer correr la rutina que subio. Gracias.

    ResponderEliminar
    Respuestas
    1. Hola...

      Lo único que debes de hacer es copiar el texto íntegro del código y pegarlo en el bloc de notas de windows... El archivo resultante lo guardas con extensión LSP y una vez guardado, lo puedes cargar en AutoCAD utilizando el comando APPLOAD, seleccionando el archivo que creaste.

      En el caso del primer código, el que puse yo, el programa se ejecuta corriendo el comando TXT2NODO... En el caso del código que se puso en el comentario, la rutina se ejecuta con el comando T2N.

      Cualquier duda, estamos a tus órdenes!

      Eliminar