Sistem simulasi skrip 3D ZenCad

Pekerjaan yang ingin saya sampaikan kepada Anda adalah upaya untuk sekali lagi menulis sistem pemodelan skrip 3D. Menulis karena saya ingin melihatnya.


Resep untuk sistem ZenCad cukup sederhana. Konsep scripting pemodelan 3D OpenScad, inti geometrik OpenCascade, python3 sebagai lem, evalcache perpustakaan komputasi malas untuk caching komputasi yang agresif. Tambahkan rempah-rempah dari beberapa instrumen lainnya, bumbui gui dengan saus PyQt, dan sajikan, aduk, tetapi jangan dikocok.


machine.png


Sistem CAD Script


CAD, atau menurut CAD kami, adalah sistem desain yang dibantu komputer. Tidak seperti editor 3D interaktif, sistem CAD scripted menafsirkan kata "otomatis" dalam arti di mana penciptanya biasanya memahaminya. Artinya, bukan sebagai seperangkat alat komputasi, tetapi sebagai algoritma yang jernih yang membutuhkan intervensi manusia hanya pada saat penciptaannya.


Bekerja dalam skrip CAD, kami tidak menggambar model langsung di layar, tetapi membangun program sesuai dengan model yang dihasilkan. Untuk orang-orang yang hanya mengenal CAD interaktif, pendekatan ini dapat digambarkan sebagai pemodelan parametrik absolut. Sebenarnya, skrip sering digunakan untuk melengkapi lingkungan interaktif, untuk menulis alat tambahan, tetapi bekerja dalam CAD skrip yang bersih secara paradigma membutuhkan organisasi yang berbeda dari alur kerja, cara berpikir, dan dirancang untuk berbagai tugas yang sedikit berbeda.


CAD scripting paling terkenal dan murni saat ini adalah OpenScad.


Pada awalnya adalah OpenScad


Ada kalangan tertentu yang lebih suka Kompas, SolidWorks, FreeCad, OpenScad yang biasa dan bersahaja. Agak sulit untuk menjawab pertanyaan apa rahasia keberhasilannya, tetapi dapat dikatakan pasti bahwa itu ringan, cukup fleksibel untuk digunakan, dan memiliki pengaturan minimum. Bagian dari model yang ditulis di atasnya mudah digunakan kembali.


Namun, openscad memiliki beberapa kelemahan yang mengganggu:


  • openscad hanya berfungsi dengan jaringan mesh.
  • openscad memiliki batas skalabilitas yang cukup rendah, ia mulai sangat tertinggal pada model besar.
  • openscad cukup sulit untuk diintegrasikan dengan sistem lain, alasannya adalah penggunaan bahasanya sendiri.

Sayangnya, untuk semua kekuatan pendekatan scripting, melampaui lingkup utilitarian flashing menulis model sederhana dengan OpenScad cukup bermasalah.


Bahasa dan semuanya


Hal pertama yang ingin saya perbaiki di sini adalah menggunakan bahasa tujuan umum sebagai alat tempur. Menggunakan bahasa tujuan umum memungkinkan Anda menggunakan kelengkapan kemampuan sintaksisnya dan kombinasi pustaka yang ditulis sebelumnya untuk menyelesaikan masalah pemodelan 3D.


Perbandingan GUI ZenCad dan OpenScad

Antarmuka ZenCad:
zencad.png


Antarmuka OpenScad:
openscad.png


Menggunakan python menyederhanakan kode openscad dengan membuat kode model lebih transparan dibandingkan dengan OpenScad.


Contoh: 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


Sangat mudah, misalnya, untuk memfilter cloud titik menggunakan sintaks generator.


Contoh: Memfilter berbagai titik.
 #!/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


Berkat python, secara tidak resmi menempati gelar raja lem dalam ekosistem perangkat lunak modern, zencad mudah diintegrasikan dengan perpustakaan dan sistem perangkat lunak lain. Kita dapat menggunakan sympy dalam satu skrip untuk menghasilkan permukaan analitis, numpy untuk memproses cloud titik yang dihasilkan pada permukaan ini, dan, tentu saja, zencad untuk membangun, memvisualisasikan, dan pasca-pemrosesan.


Contoh: Konstruksi permukaan titik-demi-titik yang sederhana
 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() 

chair.png


Dasar yang kuat dari OpenCascade


Matematika dari jerat poligonal jauh lebih sederhana daripada matematika representasi batas, tetapi representasi batas jauh lebih praktis. Secara khusus, jerat poligon memiliki masalah ledakan kombinatorial, yang memanifestasikan dirinya terutama ketika tiba saatnya untuk membuat model. Dalam OpenScad, seringkali perlu untuk mengembangkan produk dengan resolusi yang jauh lebih rendah daripada resolusi model nyata, yang melanggar kemurnian paradigma.


Dengan demikian, titik implementasi yang kedua adalah penggunaan inti geometrik penuh yang menggunakan representasi batas alih-alih model mesh. Dibangun di sekitar inti geometris hacker dari OpenCascade, ZenCad, tentu saja, tidak bertujuan untuk memberikan kepenuhan kemampuannya di lingkungan python. Mencoba sepenuhnya menyampaikan OpenCascade akan menyebabkan pythonOCC kedua ditulis. ZenCad menjadi yang teratas, berusaha menjaga keseimbangan antara fungsionalitas dan ergonomi.


Contoh: Botol perangkat lunak OpenCascade diputar di 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() 

bottle.png


Kesinambungan tradisi. Asal sebagai sumber segalanya


Solusi sintaksis zencad, mengikuti contoh kakak laki-lakinya dan guru OpenScad, meminimalkan jumlah entitas di perpustakaan. Seperti OpenScad, ZenCad pada dasarnya tidak mampu membuat primitif di titik (x, y, z), meskipun fakta bahwa OpenCascade memungkinkan ini. ZenCad pertama-tama menciptakan primitif pada asalnya, dan kemudian menetapkan posisi yang dibutuhkan menggunakan transformasi. Transformasi di ZenCad ada sebagai objek yang terpisah dan sebagai metode tubuh.


 #  . 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) 

Seperangkat transformasi adalah standar dan mencakup terjemahan, rotasi, refleksi, dan zoom.


Kemalasan


Untuk meminimalkan waktu perhitungan, matematika di ZenCad diberi lenifikasi, dan semua perhitungan di-cache secara agresif. Pustaka evalcache [del] blockchain [/ del], yang saya bicarakan di halaman Habrahabr beberapa waktu lalu, menangani pengelolaan algoritma lenifikasi: Caching disk pada pohon komputasi malas . Zencad menyimpan hasil perhitungan dalam cache umum, yang statusnya dapat dipantau melalui antarmuka visualizer. Algoritma hash sha512 digunakan dengan redundansi bertanda menghilangkan kemungkinan tabrakan kunci hash untuk objek malas (ruang hash adalah 10 ^ 74 kali jumlah atom di alam semesta).


Saat membuat model ini, ia menghasilkan empat megabita geometri dan selama lintasan pertama dapat dihitung untuk waktu yang agak lama:


bolt.png


Bekerja dengan permukaan berulir mahal secara komputasi:


logo.png


Masalah topologi refleksi. Metode titik dekat


OpenScad tidak memiliki operasi chamfering atau pembulatan. OpenCascade menyediakannya. Ini adalah operasi yang sangat penting, dan akan memalukan untuk tidak membawanya ke ZenCad. Ada operasi lain yang memerlukan menentukan objek topologi, misalnya, operasi mengambil model berdinding tipis dalam contoh botol OpenCascade. Dalam sistem CAD grafis, kami menunjukkan objek topologi (tepi, wajah, titik) dengan mouse. Saat menulis skrip, kami tidak memiliki kesempatan seperti itu. Native OpenCascade memecahkan masalah dengan refleksi dan menggunakannya untuk bekerja dengan grafik CAD. Meskipun ZenCad mendukung refleksi model, menggunakannya sebagai alat utama memiliki sejumlah kelemahan signifikan. Pertama, tingkat pengetahuan yang diperlukan untuk menggunakan alat ini meningkat tajam, karena Anda setidaknya harus memahami konsep topologi internal. Kedua, segera jika muncul dalam skrip, harmoni algoritma malas segera rusak, dan kode model juga cukup rumit. Dalam proses refleksi dan eksperimen yang cukup panjang, saya memilih metode titik dekat. Singkatnya, ketika melakukan operasi yang tergantung secara topologis, program memotong objek dan menemukan objek topologis yang paling dekat dengan titik yang diberikan dari antara mereka yang memasuki tubuh. Item ini dianggap dipilih. Solusi semacam itu lebih mahal secara komputasi, tetapi karena caching, ia bekerja dengan baik. Pendekatan ini digunakan untuk semua operasi yang bergantung pada elemen topologi.


Seperti disebutkan di atas, kemungkinan mencerminkan model, dengan akal sehat, juga dipertahankan, seperti yang ditunjukkan pada contoh di atas (Contoh: Memfilter berbagai titik).


Marker Q dan Marker W


Dimensi model bisa sulit dibaca dari layar karena tidak jelasnya skala. Sebagian, marker dapat menyelesaikan masalah ini. Memiliki antarmuka yang intuitif (tidak ada yang lebih intuitif), spidol memberi tanda koordinat dan menunjukkan jarak, yang menyederhanakan analisis geometri dan pemilihan titik untuk operasi seperti chamfer / pembulatan.


spidol


Lacak Pembaruan Sumber


Seperti kakak laki-laki (OpenScad), ZenCad dapat memperbarui model yang dihasilkan saat memodifikasi file sumber. Dalam kombinasi dengan sistem caching, ini memungkinkan Anda untuk memodifikasi skrip dengan nyaman, setelah hampir setiap saat Anda mengubah kondisi produk secara nyata.


Animasi


Manfaat zencad tidak berakhir di sana.


ZenCad (terima kasih atas pembukaan inti cepat) dapat menggambar ulang adegan secara real time, yang memungkinkan Anda untuk menghidupkan model 3D. Animasi diimplementasikan oleh fungsi python biasa dan memungkinkan Anda untuk cukup bebas memperlakukan diri sendiri. Mengingat bahwa kita berada dalam lingkungan python, zencad dapat memvisualisasikan data dari sumber eksternal sebagai gerakan model (misalnya, menggunakan multithreading + tcpsocket). Jadi, zencad dapat digunakan, misalnya, untuk pengujian semi-alami produk robot. Oh halo Gazebo !!! Hai ROS !!! Senang melihat Anda di antara hadirin juga. Perpustakaan kinematika, yang akan sangat menyederhanakan konstruksi rantai kinematik manipulator robot, omong-omong, sedang dalam pengembangan.


Animasi saat ini masih dalam versi semi-eksperimental (terutama dalam hal kontrol kamera) jadi saya tidak akan membahasnya secara rinci.


Ekspor - Impor


Saat ini, ekspor dan impor dalam format brep didukung, yang memungkinkan integrasi dengan freecad dan ekspor dalam format stl, yang memungkinkan menghasilkan model untuk pencetakan 3D. Pembuatan tangkapan layar juga didukung. Termasuk otomatis. Secara khusus, tangkapan layar dalam manual online dihasilkan secara otomatis oleh ZenCad.


Status saat ini


Saat ini, ZenCad masih sangat jauh dari penyelesaian, dan bagaimanapun itu sepenuhnya beroperasi di bagian di mana ia siap.


Perpustakaan tersedia dalam pipy untuk sumbu kompatibel Debian dengan versi python3.5, python3.6, python3.7


(Anda mungkin perlu menginstal qt5-default, karena beberapa masalah dengan plugin di PyQt5)


 python3 -m pip install zencad apt install qt5-default 

Menjalankan gui dari baris perintah:


 python3 -m zencad 

Menjalankan gui dari skrip python:


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

Sayangnya, kemajuan sistem tidak berjalan secepat yang kita inginkan. Sebagian besar api geometri dua dimensi dan api yang bekerja dengan permukaan belum diimplementasikan, dukungan untuk mengekspor dan mengimpor format standar, penanganan kesalahan tidak selalu transparan, pengujian otomatis belum berhasil, perpustakaan untuk membangun sambungan ulir dan produk peralatan telah disusun dan belum diimplementasikan. Sebagai editor eksternal, yang benar-benar abnormal, tiba-tiba menjadi hardcore !!! Sublime Text ... Saya juga benar-benar ingin memperbaiki sistem sehingga dapat dijalankan di bawah Windows (ini membutuhkan kerja intelijen ahli yang cukup banyak).


Namun, sekarang zencad memungkinkan Anda untuk merancang model 3D yang cukup kompleks, membuat model untuk pencetakan 3D, dan bahkan memvisualisasikan mekanisme kinematika.


Tautan Proyek


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


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


manual


Terima kasih atas perhatian anda


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


All Articles