How to create 3d models using Python

Hi, Habr! Once I needed to create a 3D model of the bottom, more in this article . Today I want to talk about how to create 3D models of Python 3. There are many ways to do this: blender python api, Vpython ... But I want to tell you how to make models using only Python.



Link to Github

STL


To do this, you need to understand how the stl format (the popular 3D file format) works.
The whole model in this format consists of many triangles, so the file consists of 3-dimensional coordinates of their vertices.

STL file
solid
facet normal 0 0 0
outer loop
vertex 0 0 0
vertex 1 0 0
vertex 1 1 0
endloop
endfacet
facet normal 0 0 0
outer loop
vertex 1 1 0
vertex 0 0 0
vertex 0 1 0
endloop
endfacet
endsolid

Example


I would like to show how to implement the creation of a 3D model according to the brightness of the pixels in the photo. I took this photo below.



The image is processed (slightly blurred so that there are no sharp changes in brightness) using the opencv library.

import cv2 import numpy as np cd_1=['0', '0', '0']#      1  cd_2=['0', '0', '0']#      2  cd_3=['0', '0', '0']#      3  file_stl='new.stl' file_im=r'C:\Users\allex\Pictures\2.jpg'#    op_stl=open(file_stl, 'w') op_im=cv2.imread(file_im) gray = cv2.cvtColor(op_im, cv2.COLOR_BGR2GRAY)#    blur = cv2.GaussianBlur(gray,(0,0),1)#      res=cv2.resize(blur,(320,240))#     320*240 

Bottom, a function that takes 3 arrays with coordinates of triangle vertices and writes 1 triangular face to the file

 def face_file_stl(cd_1, cd_2, cd_3): op_stl.write("facet normal 0 0 0") op_stl.write("outer loop") op_stl.write("vertex " + " ".join(cd_1))#    1  op_stl.write("vertex " + " ".join(cd_2))#    2  op_stl.write("vertex " + " ".join(cd_3))#    3  op_stl.write("endloop \n\tendfacet") 

Now the most important thing is to create the correct coordinates of the vertices of the triangles of which the 3D model consists.


The part of the code that creates the coordinates.

 for i in range(size.shape[1]):#    for k in range(size.shape[0]-1):#    if i!=size.shape[1]-1: try: #making the first triangls for relief cd_1=[str(i), str(k), str(blur[k, i]) ] cd_2=[str(i + 1), str(k), str(blur[k, i+1]) ] cd_3=[str(i+1), str(k+1), str(blur[k+1,i+1])] except: print('er') face_file_stl(cd_1, cd_2, cd_3) try: #making the second triangls for relief cd_1=[str(i), str(k), str(blur[k, i]) ] cd_2=[str(i+1), str(k+1), str(blur[k+1, i+1])] cd_3=[str(i), str(k+1), str(blur[k+1,i]) ] except: print('er') face_file_stl(cd_1, cd_2, cd_3) 

Created 3D model
Actually, this is all that I wanted to write before the next article.

All code
 import cv2 cd_1=['0', '0', '0']#      1  cd_2=['0', '0', '0']#      2  cd_3=['0', '0', '0']#      3  file_stl='new.stl' file_im=r'C:\Users\allex\Pictures\22.jpg'#    op_stl=open(file_stl, 'w') op_im=cv2.imread(file_im) gray = cv2.cvtColor(op_im, cv2.COLOR_BGR2GRAY)#    blur = cv2.GaussianBlur(gray,(0,0),1)#      blur=cv2.resize(blur,(320,240)) x=0 y=0 file='STL_project-1.stl' o_1="\n\t" o_2="\n\t\t" o_3="\n\t\t\t" op_stl.write("solid") def face_file_stl(cd_1, cd_2, cd_3): op_stl.write(o_1+"facet normal 0 0 0") op_stl.write(o_2 + "outer loop") op_stl.write(o_3 + "vertex " + " ".join(cd_1))#    1  op_stl.write(o_3 + "vertex " + " ".join(cd_2))#    2  op_stl.write(o_3 + "vertex " + " ".join(cd_3))#    3  op_stl.write(o_2 + "endloop \n\tendfacet") #making the first triangls for base for i in range(blur.shape[1]-1): cd_1=[str(i),"0","0"] cd_3=[str(i+1),str(blur.shape[0]-1),"0"] cd_2=[str(i),str(blur.shape[0]-1),"0"] face_file_stl(cd_1, cd_2, cd_3) #making the second triangls for base for i in range(blur.shape[1]-1): cd_1=[str(i+1),str(blur.shape[0]-1),"0"] cd_3=[str(i),"0","0"] cd_2=[str(i+1),"0","0"] face_file_stl(cd_1, cd_2, cd_3) #base has done for i in range(blur.shape[1]): if i%30==0: print(i) for k in range(blur.shape[0]-1):#making the first triangls for relief if i!=blur.shape[1]-1: try: cd_1=[str(i), str(k), str(blur[k, i]) ] cd_2=[str(i + 1), str(k), str(blur[k, i+1]) ] cd_3=[str(i+1), str(k+1), str(blur[k+1,i+1])] except: print('er') face_file_stl(cd_1, cd_2, cd_3) #for j in range(blur.shape[1]-1):#making the second triangls for relief try: cd_1=[str(i), str(k), str(blur[k, i]) ] cd_2=[str(i+1),str(k+1), str(blur[k+1, i+1])] cd_3=[str(i), str(k+1), str(blur[k+1,i]) ] except: print('er') face_file_stl(cd_1, cd_2, cd_3) #relief has done #making the first triangls for right side for i in range(blur.shape[1]): if i!=blur.shape[1]-1: try: cd_1=[str(i),str(blur.shape[0]-1),"0"] cd_3=[str(i+1),str(blur.shape[0]-1),str(blur[blur.shape[0]-1, i+1])] cd_2=[str(i),str(blur.shape[0]-1),str(blur[blur.shape[0]-1, i])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) #making the second triangls for right side try: cd_1=[str(i),str(blur.shape[0]-1),"0"] cd_3=[str(i+1),str(blur.shape[0]-1),"0"] cd_2=[str(i+1),str(blur.shape[0]-1),str(blur[blur.shape[0]-1, i+1])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) if i!=blur.shape[1]-1: try: cd_1=[str(i),'0',"0"] cd_2=[str(i+1),'0',str(blur[0, i+1])] cd_3=[str(i),'0',str(blur[0, i])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) #making the second triangls for right side try: cd_1=[str(i),'0',"0"] cd_2=[str(i+1),'0',"0"] cd_3=[str(i+1),'0',str(blur[0, i+1])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) for i in range(blur.shape[0]): if i!=blur.shape[0]-1: try: cd_1=['0',str(i),"0"] cd_3=['0',str(i+1),str(blur[ i+1,0])] cd_2=['0',str(i),str(blur[i,0])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) #making the second triangls for right side try: cd_1=['0',str(i),"0"] cd_3=['0',str(i+1),"0"] cd_2=['0',str(i+1),str(blur[i+1,0])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) try: cd_2=[str(blur.shape[1]-1),str(i),"0"] cd_3=[str(blur.shape[1]-1),str(i+1),str(blur[ i+1,blur.shape[1]-1])] cd_1=[str(blur.shape[1]-1),str(i),str(blur[i,blur.shape[1]-1])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) #making the second triangls for right side try: cd_2=[str(blur.shape[1]-1),str(i),"0"] cd_3=[str(blur.shape[1]-1),str(i+1),"0"] cd_1=[str(blur.shape[1]-1),str(i+1),str(blur[i+1,blur.shape[1]-1])] except: print("er") face_file_stl(cd_1, cd_2, cd_3) op_stl.write("\nendsolid" ) op_stl.close() print('end') 

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


All Articles