3D Baskıya Hazır CAD Tasarımlarına Erişmek, Numpy-STL
3 boyutlu baskı (3d printing) için tasarım dosyaları hazırlamaya yardım eden STL formatı var. Bir objeyi mesela Tinkercad ile tasarlayıp objeyi STL formatında kaydedebiliriz, bu dosya 3 boyutlu baskıya hazırdır.
Örnek bir objeye bakalım [1], bir pervane bu, propeller1.stl
olarak
kaydedelim. Obje tasarımına, verisine Python'dan erişmek istersek,
numpy-stl
kullanılabilir.
pip install numpy-stl
Şimdi
from stl import mesh
from mpl_toolkits import mplot3d
# Create a new plot
figure = plt.figure()
axes = mplot3d.Axes3D(figure)
# Load the STL files and add the vectors to the plot
your_mesh = mesh.Mesh.from_file('propeller1.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))
# Auto scale to the mesh size
scale = your_mesh.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)
# Show the plot to the screen
plt.savefig('prop.png')
Daha detaylı işlemler için dokümana [2] bakılabilir,
STL Veri Yapısı
Şekil dosyaları bir objenin yüzeyini kapsayan ve birbirini tamamlayan üçgenler üzerinden tanımlanıyor. Bu yassı iki boyutlu üçgenleri temsil etmek için üç tane 3D nokta bir de yüzeyin hangi yöne işaret ettiği (bir normal vektör üzerinden) yeterli. Mesela biraz önceki şekil için,
from stl import mesh
from mpl_toolkits import mplot3d
your_mesh = mesh.Mesh.from_file('propeller1.stl')
print (len(your_mesh.vectors))
ns = your_mesh.get_unit_normals()
print (ns.shape)
print (your_mesh.vectors[0])
7668
(7668, 3)
[[ 42.881 -14.357 0.562]
[ 43.095 -15.066 0.752]
[ 41.793 -14.443 0.463]]
Görüldüğü gibi 7668 tane üçgen ve normal vektör var. Üçgenlerden
sıfırıncı olana baktık ve üstteki 3x3 matris geldi, bu matrislerden
ilk satır üçgenin bir köşesi, ikinci satır ikinci köşesi, vs. Aynı
üçgene tekabül eden normal vektör yine aynı indiste, onu
your_mesh.get_unit_normals()[0]
ile alabilirdik.
Üçgenler hakkında bir fikir olması için iki tanesini, normalleriyle beraber grafikleyelim,
fig = plt.figure()
axes = mplot3d.Axes3D(fig)
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
scale = your_mesh.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)
def plot_vector(fig, orig, v, color='blue'):
ax = fig.gca(projection='3d')
orig = np.array(orig); v=np.array(v)
ax.quiver(orig[0], orig[1], orig[2], v[0], v[1], v[2],color=color)
ax = fig.gca(projection='3d')
return fig
SCALE = 30
tidx = 2314
tc = your_mesh.vectors[tidx][0]
axes.plot (tc[0],tc[1],tc[2],'r.')
tc = your_mesh.vectors[tidx][1]
axes.plot (tc[0],tc[1],tc[2],'r.')
tc = your_mesh.vectors[tidx][2]
axes.plot (tc[0],tc[1],tc[2],'r.')
o = np.mean(your_mesh.vectors[tidx],axis=0)
n = your_mesh.get_unit_normals()[tidx]
plot_vector(fig, o, n*SCALE)
tidx = 314
tc = your_mesh.vectors[tidx][0]
axes.plot (tc[0],tc[1],tc[2],'r.')
tc = your_mesh.vectors[tidx][1]
axes.plot (tc[0],tc[1],tc[2],'r.')
tc = your_mesh.vectors[tidx][2]
axes.plot (tc[0],tc[1],tc[2],'r.')
o = np.mean(your_mesh.vectors[tidx],axis=0)
n = your_mesh.get_unit_normals()[tidx]
plot_vector(fig, o, n*SCALE)
axes.set_xlim(20,40);axes.set_ylim(-10,-20)
plt.savefig('prop2.png')
İki tane üçgeni gösterdik, yön oklarında okun başlangıcı için üçgenin üç
noktasının ortalamasını aldık, böylece kabaca bir orta noktadan çıkan
SCALE
ile ölçeklediğimiz normal yönde bir ok çizebilmiş olduk.
Özet Verileri
Küre, kare gibi basit objelerin analitik hacim formülü bilinir. Fakat
elimizde çetrefil bir şekilde ve ayrıksal olarak yüzeyi tanımlanmış
bir nesne var, onun hacmi için ayrıksal, hesapsal bazı teknikler
gerekebilirdi, neyse ki numpy-stl
içinde bu fonksiyonlar var,
prop = your_mesh.get_mass_properties()
print ('\nhacim',prop[0])
print ('\nyercekim merkezi (COG)',prop[1])
print ('\nCOG noktasinda atalet matrisi')
print (prop[2])
hacim 508.81107187133966
yercekim merkezi (COG) [ 14.99940119 -14.99999338 1.13988199]
COG noktasinda atalet matrisi
[[ 2.14550670e+03 -2.23269194e-03 -2.31301332e-02]
[-2.23269194e-03 1.01219910e+05 6.33494132e+01]
[-2.31301332e-02 6.33494132e+01 1.02767050e+05]]
3D Döndürme
Bir objeyi döndürmek için gereken matematiği [6]'da görmüştük. Eğer bir simit
şeklindeki bir objeyi bir eksen, mesela x, etrafında döndürmek istiyorsak,
gerekli döndürme matris şekli [6]'da işlendi. Bu matris yaratıldıktan sonra
mesh üzerinde rotate_using_matrix
çağrısı yapılabilir. Matrisi yaratmanın
farklı yolları var tabii, bunlar detaylı olarak yazıda işlendi. Örnek olarak
yatay şekilde başlayan bir simit (torus) şeklini x ekseni etrafında 90 derece
döndürelim,
from mpl_toolkits import mplot3d
import numpy as np
from stl import mesh
fig = plt.figure()
axes = mplot3d.Axes3D(fig)
your_mesh = mesh.Mesh.from_file('../../../phy/phy_008_sim_rigbod/torus.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
scale = your_mesh.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)
AS = 3
axes.plot([0,AS],[0,0],[0,0],color = 'r')
axes.plot([0,0],[0,AS],[0,0],color = 'g')
axes.plot([0,0],[0,0],[0,AS],color = 'b')
LIM = 5
axes.set_xlim(-LIM,LIM);axes.set_ylim(-LIM,LIM);axes.set_zlim(-LIM,LIM)
axes.view_init(azim=40,elev=30)
plt.savefig('torus-begin.png')
your_mesh = mesh.Mesh.from_file('../../../phy/phy_005_basics_04/torus.stl')
theta = np.deg2rad(90) # 90 derece x ekseni etrafinda dondur
R = np.array(
[[1, 0, 0],
[0,np.cos(theta),np.sin(theta)],
[0,-np.sin(theta),np.cos(theta)]])
print (R)
your_mesh.rotate_using_matrix(R)
fig = plt.figure()
axes = mplot3d.Axes3D(fig)
scale = your_mesh.points.flatten()
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors,alpha=0.3))
AS = 3
axes.plot([0,AS],[0,0],[0,0],color = 'r')
axes.plot([0,0],[0,AS],[0,0],color = 'g')
axes.plot([0,0],[0,0],[0,AS],color = 'b')
axes.auto_scale_xyz(scale, scale, scale)
LIM = 5
axes.set_xlim(-LIM,LIM);axes.set_ylim(-LIM,LIM);axes.set_zlim(-LIM,LIM)
axes.view_init(azim=40,elev=20)
plt.savefig('torus-rotated.png')
[[ 1.000000e+00 0.000000e+00 0.000000e+00]
[ 0.000000e+00 6.123234e-17 1.000000e+00]
[ 0.000000e+00 -1.000000e+00 6.123234e-17]]
Ekler
STL dosyalarını çabuk bir şekilde Ubuntu'da görebilmek için, bir program meshlab
.
sudo apt-get install meshlab
meshlab dosya.stl
Kaynaklar
[1] [Tinkercad](https://www.tinkercad.com/things/h3gtFbihOx3-helice-2-pales-arrondies-propeller-2-rounded-blades)
[2] [Numpy STL](https://pythonhosted.org/numpy-stl/)
[3] [C++ ile STL Dosyasi Okumak](http://www.sgh1.net/posts/read-stl-file.html)
[4] [Cornell, Triangle meshes I, PDF](http://www.cs.cornell.edu/courses/cs4620/2014fa/lectures/02trimesh1.pdf)
[5] [STL File Format, Simply Explained](https://all3dp.com/what-is-stl-file-format-extension-3d-printing/#pointone)
[6] [Döndürme (Rotation)](https://burakbayramli.github.io/dersblog/phy/phy072rot/dondurme_rotation.html)
Yukarı