Sistema de simulación de script ZenCad 3D

El trabajo que quiero llamar su atención es un intento de escribir una vez más un sistema de modelado 3D con guión. Escribe como me gustaría verla.


La receta para el sistema ZenCad es bastante simple. El concepto de modelado 3D de scripts de OpenScad, el núcleo geométrico de OpenCascade, python3 como pegamento, la biblioteca de computación diferida evalcache para el almacenamiento en caché agresivo de los cálculos. Agregue especias de un par de otras herramientas, sazone la gui con salsa PyQt y sirva, revolviendo, pero sin agitar.


máquina.png


Script CAD Systems


CAD, o según nuestro CAD, es un sistema de diseño asistido por computadora. A diferencia de los editores 3D interactivos, los sistemas CAD con secuencias de comandos interpretan la palabra "automatizado" en el sentido en que sus creadores generalmente la entienden. Es decir, no como un conjunto de herramientas informáticas, sino como un algoritmo cristalino que requiere intervención humana solo en el momento de su creación.


Al trabajar en CAD con script, no dibujamos el modelo directamente en la pantalla, sino que construimos el programa según el cual se genera el modelo. Para las personas que solo están familiarizadas con el CAD interactivo, este enfoque puede describirse como un modelado paramétrico absoluto. Estrictamente hablando, los scripts a menudo se usan para complementar un entorno interactivo, para escribir herramientas adicionales, pero trabajar en un CAD con scripts paradigmáticamente limpio requiere una organización diferente del flujo de trabajo, una forma de pensar, y está diseñado para una gama de tareas ligeramente diferente.


El CAD de scripting más famoso y puro en este momento es OpenScad.


Al principio fue OpenScad


Hay un cierto círculo de personas que prefieren el conveniente Compass, SolidWorks, FreeCad, el OpenScad mundano y sin pretensiones. Es bastante difícil responder la pregunta de cuál es el secreto de su éxito, pero se puede decir con certeza que es liviano, lo suficientemente flexible como para usar y tiene un mínimo de configuraciones. Partes de los modelos escritos en él son fáciles de reutilizar.


Sin embargo, openscad tiene algunos defectos molestos:


  • openscad solo funciona con redes de malla.
  • openscad tiene un límite de escalabilidad bastante bajo, comienza a retrasarse mucho en modelos grandes.
  • openscad es bastante difícil de integrar con otros sistemas, la razón por la cual es el uso de su propio lenguaje.

Desafortunadamente, a pesar de todo el poder del enfoque de secuencias de comandos, ir más allá del alcance del flasheo utilitario escribiendo modelos simples con OpenScad es bastante problemático.


Lenguaje y todo-todo-todo


Lo primero que quiero arreglar aquí es tomar un lenguaje de propósito general como herramienta de combate. El uso de un lenguaje de propósito general le permite utilizar la integridad de sus capacidades sintácticas y la combinación de bibliotecas previamente escritas para resolver problemas de modelado 3D.


Comparación de las GUI de ZenCad y OpenScad

Interfaz ZenCad:
zencad.png


Interfaz OpenScad:
openscad.png


El uso de python simplifica el código de openscad al hacer que el código del modelo sea más transparente en comparación con OpenScad.


Ejemplo: CSG
#!/usr/bin/env python #coding: utf-8 from zencad import * lazy.diag = True c1 = 100 c2 = 130 c3 = c2/2 + 20 base = box(c1,c1,c1,center=True) f1 = ngon(r = 35, n = 3) f2 = ngon(r = 35, n = 5) f3 = circle(35) s1 = linear_extrude(f1, c2, center=True) s2 = linear_extrude(f2, c2, center=True).rotateY(deg(90)) s3 = linear_extrude(f3, c2, center=True).rotateX(deg(90)) #          3 . m1 = base - s1 - s2 - s3 m2 = base ^ s1 ^ s2 ^ s3 m3 = s1 + s2 + s3 ystep = 240 xstep = 240 fontpath = os.path.join(zencad.moduledir, "examples/fonts/testfont.ttf") #    .      . t1 = textshape("difference", fontpath, 40) t1c = t1.center() t1=t1.translate(-t1c.x, -t1c.y, 0).rotateZ(deg(45)) t2 = textshape("intersect", fontpath, 40) t2c = t2.center() t2=t2.translate(-t2c.x, -t2c.y, 0).rotateZ(deg(45)) t3 = textshape("union", fontpath, 40) t3c = t3.center() t3=t3.translate(-t3c.x, -t3c.y, 0).rotateZ(deg(45)) #  ,  . disp(base.forw(ystep)) disp(s1) disp(s2.left(xstep)) disp(s3.right(xstep)) disp(m1.back(ystep)) disp(m2.left(xstep).back(ystep)) disp(m3.right(xstep).back(ystep)) disp(t1.back(ystep).up(c3), Color(1,1,0)) disp(t2.left(xstep).back(ystep).up(c3), Color(1,1,0)) disp(t3.right(xstep).back(ystep).up(c3), Color(1,1,0)) disp(s1.left(xstep).back(ystep), Color(0.5,0,0,0.95)) disp(s2.left(xstep).back(ystep), Color(0.5,0,0,0.95)) disp(s3.left(xstep).back(ystep), Color(0.5,0,0,0.95)) disp(s1.back(ystep), Color(0.5,0,0,0.95)) disp(s2.back(ystep), Color(0.5,0,0,0.95)) disp(s3.back(ystep), Color(0.5,0,0,0.95)) show() 

boolean.png


Es muy conveniente, por ejemplo, filtrar una nube de puntos utilizando la sintaxis de los generadores.


Ejemplo: filtrado de una matriz de puntos.
 #!/usr/bin/env python3 from zencad import * #  . ng = ngon(r = 10, n = 6) #      . vertices = ng.vertices() filtered_vertices = [v for v in vertices if vx < 0] #      . m = ng.fillet(4, filtered_vertices) disp(m) show() 

ngon


Gracias a Python, que ocupa no oficialmente el título de rey del pegamento en el ecosistema de software moderno, zencad se integra fácilmente con otras bibliotecas y sistemas de software. Podemos usar sympy en un script para generar una superficie analítica, numpy para procesar una nube de puntos generada en esta superficie y, por supuesto, zencad para construir, visualizar y postprocesar.


Ejemplo: construcción de superficie simple punto por punto
 from zencad import * import numpy xcoords = numpy.linspace(-10,10,50) ycoords = numpy.linspace(-10,15,50) lines = [ interpolate([point(x, y, 0.01*(x**2 + y**3)) for x in xcoords]) for y in ycoords ] wires = [] for l in lines: trans = translate(0,0,-30) sf = l.endpoints() w=sew([l, segment(sf[0], trans(sf[0])), trans(l), segment(sf[1], trans(sf[1]))]) wires.append(w) for l in lines: disp(l.left(30)) disp(loft(wires) - halfspace().down(10)) show() 

silla.png


La base sólida de OpenCascade


La matemática de las mallas poligonales es mucho más simple que la matemática de la representación de límites, pero la representación de límites es mucho más práctica. En particular, las mallas poligonales tienen un problema de explosión combinatoria, que se manifiesta especialmente cuando llega el momento de renderizar un modelo. En OpenScad, a menudo es necesario desarrollar un producto con una resolución mucho más baja que la resolución de un modelo real, lo que viola la pureza del paradigma.


Por lo tanto, el segundo punto de implementación es el uso de un núcleo geométrico completo que utiliza la representación de límites en lugar del modelo de malla. Construido alrededor del núcleo geométrico hacker de OpenCascade, ZenCad, por supuesto, no tiene como objetivo proporcionar la totalidad de sus capacidades en el entorno python. Intentar transmitir completamente OpenCascade llevaría a que se escriba un segundo pythonOCC. ZenCad toma la delantera, tratando de mantener un equilibrio entre funcionalidad y ergonomía.


Ejemplo: la botella de software OpenCascade se reproduce en ZenCad
 #!/usr/bin/env python3 #coding: utf-8 from zencad import * import zencad.surface as surface import zencad.curve2 as curve2 lazy.diag=True height = 70 width = 50 thickness = 30 # BASE pnt1 = point(-width/2,0,0); pnt2 = point(-width/2,-thickness/4,0); pnt3 = point(0,-thickness/2,0); pnt4 = point(width/2,-thickness/4,0); pnt5 = point(width/2,0,0); edge1 = segment(pnt1, pnt2) edge2 = circle_arc(pnt2, pnt3, pnt4) edge3 = segment(pnt4, pnt5) wire = sew([edge1, edge2, edge3]) profile = sew([wire, wire.mirrorX()]) body = profile.fill().extrude(height) body = fillet(body, thickness/12) hl(body.forw(140)) # NECK neck_radius = thickness/4.; neck_height = height/10; neck = cylinder(r=neck_radius, h=neck_height).up(height) body = body + neck hl(body.forw(100)) # THICK body = thicksolid(body, -thickness / 50, [point(0,0,height+height/10)]) hl(body.forw(60)) # THREAD ( 2       .) cylsurf1 = surface.cylinder(neck_radius * 0.99) cylsurf2 = surface.cylinder(neck_radius * 1.05) major = 2 * math.pi; minor = neck_height / 10; angle = math.atan2(neck_height / 4, 2 * math.pi) ellipse1 = curve2.ellipse(major, minor).rotate(angle) arc1 = cylsurf1.map(curve2.trimmed_curve2(ellipse1, 0, math.pi)) segment1 = cylsurf1.map(curve2.segment(ellipse1.value(0), ellipse1.value(math.pi))) ellipse2 = curve2.ellipse(major, minor/4).rotate(angle) arc2 = cylsurf2.map(curve2.trimmed_curve2(ellipse2, 0, math.pi)) segment2 = cylsurf2.map(curve2.segment(ellipse2.value(0), ellipse2.value(math.pi))) m1 = sew([arc1, segment1]) m2 = sew([arc2, segment2]) thread = loft([m1, m2]).up(height + neck_height / 2) hl(m1.up(height + neck_height / 2).right(80)) hl(m2.up(height + neck_height / 2).right(60)) hl(thread.right(40)) # FINAL m = thread + body display(m) show() 

botella.png


Continuidad de la tradición. El origen como fuente de todo.


Las soluciones de sintaxis de zencad, siguiendo el ejemplo de su hermano mayor y maestro de OpenScad, minimizan el número de entidades en la biblioteca. Al igual que OpenScad, ZenCad es fundamentalmente incapaz de crear una primitiva en el punto (x, y, z), a pesar de que OpenCascade lo permite. ZenCad primero crea una primitiva en el origen, y luego establece la posición que necesita usando transformaciones. Las transformaciones en ZenCad existen tanto como objetos separados como como métodos de cuerpos.


 #  . cube(40, center=True).rotateX(deg(45)).rotateZ(deg(45)).right(20) #  . (right(20) * rotateZ(deg(45)) * rotateX(deg(45)))(cube(40, center=True)) #  . trans = right(20) * rotateZ(deg(45)) * rotateX(deg(45)) cube(40, center=True).transform(trans) 

Un conjunto de transformaciones es estándar e incluye traslación, rotación, reflexión y zoom.


Pereza


Para minimizar el tiempo de cálculo, las matemáticas en ZenCad se lenifican y todos los cálculos se almacenan en caché de forma agresiva. La biblioteca [del] blockchain [/ del] evalcache, de la que hablé en las páginas de Habrahabr hace algún tiempo, se encarga de la gestión de algoritmos de lenificación: almacenamiento en caché de disco de árboles informáticos perezosos . Zencad guarda los resultados del cálculo en una memoria caché común, cuyo estado se puede monitorear a través de la interfaz del visualizador. El algoritmo hash sha512 utilizado con redundancia marcada elimina la posibilidad de colisiones de claves hash de objetos perezosos (el espacio hash es 10 ^ 74 veces el número de átomos en el universo).


Al crear este modelo, genera cuatro megabytes de geometría y durante la primera pasada se puede calcular durante un tiempo bastante largo:


bolt.png


El trabajo con superficies roscadas es computacionalmente costoso:


logo.png


El problema de la topología de la reflexión. Método de punto cercano


OpenScad no tiene operaciones de chaflán o redondeo. OpenCascade los proporciona. Estas son operaciones muy importantes, y sería una pena no tenerlas en servicio para ZenCad. Hay otras operaciones que requieren especificar un objeto topológico, por ejemplo, la operación de tomar un modelo de pared delgada en el ejemplo de botella de OpenCascade. En un sistema CAD gráfico, indicamos un objeto topológico (borde, cara, vértice) con el mouse. Al escribir un guión, no tenemos esa oportunidad. Native OpenCascade resuelve el problema con la reflexión y lo utiliza para trabajar con CAD gráfico. Aunque ZenCad admite la reflexión del modelo, su uso como herramienta principal tiene varios inconvenientes importantes. En primer lugar, el nivel de conocimiento requerido para usar estas herramientas aumenta drásticamente, porque al menos debe comprender el concepto topológico interno. En segundo lugar, tan pronto como aparece en el script, la armonía de los algoritmos perezosos se rompe inmediatamente, y el código del modelo también es bastante complicado. En el proceso de reflexión y experimentación bastante largo, me decidí por el método del punto cercano. En resumen, cuando se realizan operaciones topológicamente dependientes, el programa evita el objeto y encuentra el objeto topológico más cercano al punto dado entre los que ingresan al cuerpo. Este artículo se considera seleccionado. Tal solución es más costosa computacionalmente, pero debido al almacenamiento en caché, funciona bien. Este enfoque se utiliza para todas las operaciones que dependen de elementos de topología.


Como se mencionó anteriormente, la posibilidad de reflejar el modelo, por sentido común, también se conserva, como se muestra en el ejemplo anterior (Ejemplo: Filtrar una matriz de puntos).


Marcador Q y Marcador W


Las dimensiones del modelo pueden ser difíciles de leer desde la pantalla debido a la falta de evidencia de la escala. En parte, los marcadores pueden resolver este problema. Al tener una interfaz intuitiva (en ningún lugar más intuitiva), los marcadores señalan las coordenadas y muestran la distancia, lo que simplifica el análisis de la geometría y la selección de puntos para operaciones tales como chaflanes / redondeo.


marcadores


Seguimiento de actualizaciones de origen


Al igual que el hermano mayor (OpenScad), ZenCad puede actualizar el modelo generado al modificar el archivo fuente. En combinación con el sistema de almacenamiento en caché, esto le permite modificar de manera bastante conveniente el script, teniendo ante sus ojos casi en tiempo real el estado cambiante del producto.


Animación


Los méritos de zencad no terminan ahí.


ZenCad (gracias a la rápida cascada de núcleo abierto) puede volver a dibujar la escena en tiempo real, lo que le permite animar un modelo 3D. La animación se implementa mediante una función de python ordinaria y le permite tratarse con bastante libertad. Dado que estamos en un entorno de python, zencad puede visualizar datos de fuentes externas como movimientos de modelo (por ejemplo, usando multihilo + tcpsocket). Por lo tanto, zencad puede usarse, por ejemplo, para pruebas semi-naturales de productos robóticos. Oh hola Gazebo !!! Hola ROS !!! Es bueno verte en la audiencia también. Una biblioteca de cinemática, que simplificaría enormemente la construcción de cadenas cinemáticas de manipuladores robóticos, por cierto, está en desarrollo.


La animación en este momento todavía está en una versión semi-experimental (especialmente en términos de control de la cámara), por lo que no me detendré en ella en detalle.


Exportar - Importar


Actualmente, se admite la exportación e importación en formato brep, lo que permite la integración con freecad y la exportación en formato stl, lo que permite generar modelos para la impresión 3D. La generación de capturas de pantalla también es compatible. Incluyendo automático. En particular, las capturas de pantalla en el manual en línea son generadas automáticamente por ZenCad.


Estado actual


Por el momento, ZenCad todavía está muy lejos de completarse y, sin embargo, está completamente operativo en la parte en la que está listo.


La biblioteca está disponible en pipy para ejes compatibles con Debian con versiones de python3.5, python3.6, python3.7


(Es posible que deba instalar qt5-default, debido a algunos problemas con los complementos en PyQt5)


 python3 -m pip install zencad apt install qt5-default 

Ejecutando gui desde la línea de comando:


 python3 -m zencad 

Ejecutar gui desde un script de python:


 #!/usr/bin/env python3 import zencad m = zencad.cube(20) zencad.disp(m) zencad.show() 

Lamentablemente, el progreso del sistema no va tan rápido como nos gustaría. La mayor parte de la API de geometría bidimensional y la API de trabajar con superficies aún no se han implementado, el soporte para exportar e importar formatos estándar, el manejo de errores no siempre es transparente, las pruebas automáticas no se han resuelto, las bibliotecas para construir juntas roscadas y productos de engranajes se han concebido y aún no se han implementado. Como editor externo, que es completamente anormal, ¡de repente es duro! Texto sublime ... También quiero perfeccionar el sistema para que pueda ejecutarse en Windows (esto requiere bastante trabajo de inteligencia experto).


Sin embargo, ahora zencad le permite diseñar modelos 3D bastante complejos, crear modelos para impresión 3D e incluso visualizar la cinemática de los mecanismos.


Enlaces de proyectos


github: https://github.com/mirmik/zencad , https://github.com/mirmik/servoce


pypi: https://pypi.org/project/zencad/ , https://pypi.org/project/pyservoce/


manual


Gracias por su atencion


Source: https://habr.com/ru/post/443140/


All Articles