|
|
@ -91,22 +91,22 @@ class app:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.mode = "3d"
|
|
|
|
self.mode = "3d"
|
|
|
|
|
|
|
|
|
|
|
|
if len(self.args.stl_file) < 4:
|
|
|
|
if len(self.args.stl_file) < 5:
|
|
|
|
self.height_line = 2
|
|
|
|
self.height_line = 2
|
|
|
|
|
|
|
|
self.height_base = 10
|
|
|
|
self.curv_rate_x = 0.5
|
|
|
|
self.curv_rate_x = 0.5
|
|
|
|
self.curv_rate_y = 0.5
|
|
|
|
self.curv_rate_y = 0.5
|
|
|
|
print(
|
|
|
|
print(
|
|
|
|
"Warning: Too few arguments, using default values (2mm lines, curvature 0.5 on x, 0.5 on y)")
|
|
|
|
"Warning: Too few arguments, using default values (2mm lines, curvature 0.5 on x, 0.5 on y)")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.height_line = float(self.args.stl_file[1])
|
|
|
|
self.height_line = float(self.args.stl_file[1])
|
|
|
|
|
|
|
|
self.height_base = float(self.args.stl_file[2])
|
|
|
|
self.curv_rate_x = float(
|
|
|
|
self.curv_rate_x = float(
|
|
|
|
self.args.stl_file[2]) # finger depth
|
|
|
|
|
|
|
|
self.curv_rate_y = float(
|
|
|
|
|
|
|
|
self.args.stl_file[3]) # finger depth
|
|
|
|
self.args.stl_file[3]) # finger depth
|
|
|
|
# self.curv_rate_x = float(self.args.stl_file[2]) # excentricity x
|
|
|
|
self.curv_rate_y = float(
|
|
|
|
# self.curv_rate_y = float(self.args.stl_file[3]) # excentricity y
|
|
|
|
self.args.stl_file[4]) # finger depth
|
|
|
|
print("Line height:", self.height_line,"mm, x axis curvature:", self.curv_rate_x,
|
|
|
|
print("Line height:", self.height_line, "mm, base height: ", self.height_base,
|
|
|
|
", y axis curvature:", self.curv_rate_y)
|
|
|
|
"mm, x axis curvature: ", self.curv_rate_x, ", y axis curvature:", self.curv_rate_y)
|
|
|
|
|
|
|
|
|
|
|
|
print(self.mode, "mode selected")
|
|
|
|
print(self.mode, "mode selected")
|
|
|
|
self.run_stl()
|
|
|
|
self.run_stl()
|
|
|
@ -241,20 +241,21 @@ class app:
|
|
|
|
In case none were given, pass and save original image to the output file.
|
|
|
|
In case none were given, pass and save original image to the output file.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
if len(self.filters) == 0:
|
|
|
|
if len(self.filters) != 0:
|
|
|
|
pass
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
# Apply all filters
|
|
|
|
# Apply all filters
|
|
|
|
for i, filter_name in enumerate(self.filters):
|
|
|
|
for i, filter_name in enumerate(self.filters):
|
|
|
|
# Get filter class from filter.py, use the apply method
|
|
|
|
# Get filter class from filter.py, use the apply method
|
|
|
|
filter = getattr(flt, filter_name)
|
|
|
|
filter = getattr(flt, filter_name)
|
|
|
|
filter.apply(self, self.params[i+1])
|
|
|
|
filter.apply(self, self.params[i+1])
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def save_image(self, fig, ax):
|
|
|
|
def save_image(self, fig, ax):
|
|
|
|
'''Save processed image to the output file.
|
|
|
|
'''Save processed image to the output file.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
print("Saving image to", self.output_file, file=sys.stderr)
|
|
|
|
print("Saving image to", self.output_file, file=sys.stderr)
|
|
|
|
|
|
|
|
|
|
|
|
# Colormap must be set to grayscale to avoid color mismatch.
|
|
|
|
# Colormap must be set to grayscale to avoid color mismatch.
|
|
|
|
ax.imshow(self.img, cmap="gray")
|
|
|
|
ax.imshow(self.img, cmap="gray")
|
|
|
|
fig.savefig(fname=self.output_file, dpi=self.dpi)
|
|
|
|
fig.savefig(fname=self.output_file, dpi=self.dpi)
|
|
|
@ -266,8 +267,9 @@ class app:
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
self.prepare_heightmap()
|
|
|
|
self.prepare_heightmap()
|
|
|
|
self.get_ID()
|
|
|
|
self.get_ID()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Create a mesh using one of two modes
|
|
|
|
if self.mode == "2d":
|
|
|
|
if self.mode == "2d":
|
|
|
|
self.make_stl_planar()
|
|
|
|
self.make_stl_planar()
|
|
|
|
|
|
|
|
|
|
|
@ -343,7 +345,7 @@ class app:
|
|
|
|
# paint the background black
|
|
|
|
# paint the background black
|
|
|
|
ax.plot([0, 1], [0, 1], c="black", lw=self.width)
|
|
|
|
ax.plot([0, 1], [0, 1], c="black", lw=self.width)
|
|
|
|
|
|
|
|
|
|
|
|
# extract text from filename
|
|
|
|
# extract filename
|
|
|
|
text = self.stl_file.split("/")[-1].split(".")[0] + self.id
|
|
|
|
text = self.stl_file.split("/")[-1].split(".")[0] + self.id
|
|
|
|
fontsize = 20
|
|
|
|
fontsize = 20
|
|
|
|
|
|
|
|
|
|
|
@ -369,10 +371,15 @@ class app:
|
|
|
|
plt.close()
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: maybe don't use nested for loops, use numpy?
|
|
|
|
# TODO: maybe don't use nested for loops, use numpy?
|
|
|
|
for i in range(self.height):
|
|
|
|
if self.mode == "2d":
|
|
|
|
for j in range(self.width):
|
|
|
|
for i in range(self.height):
|
|
|
|
bottom_vert_arr[i][j][2] = data[i][j][0]
|
|
|
|
for j in range(self.width):
|
|
|
|
|
|
|
|
bottom_vert_arr[i][j][2] = data[i][j][0]
|
|
|
|
|
|
|
|
elif self.mode == "3d":
|
|
|
|
|
|
|
|
for i in range(self.height):
|
|
|
|
|
|
|
|
for j in range(self.width):
|
|
|
|
|
|
|
|
bottom_vert_arr[i][j][2] += data[i][j][0] - self.height_base
|
|
|
|
|
|
|
|
|
|
|
|
return bottom_vert_arr
|
|
|
|
return bottom_vert_arr
|
|
|
|
|
|
|
|
|
|
|
|
def create_stl_mesh(self, faces, vertices):
|
|
|
|
def create_stl_mesh(self, faces, vertices):
|
|
|
@ -498,29 +505,23 @@ class app:
|
|
|
|
* (self.curv_rate_y**2))
|
|
|
|
* (self.curv_rate_y**2))
|
|
|
|
z[y] = z[y] + new
|
|
|
|
z[y] = z[y] + new
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: clip responsivelly to save material used to print the model
|
|
|
|
|
|
|
|
#bottom = z[0][math.floor(self.width/2)]
|
|
|
|
|
|
|
|
z = z.reshape(-1, 1)
|
|
|
|
z = z.reshape(-1, 1)
|
|
|
|
|
|
|
|
z_cpy = np.copy(z)
|
|
|
|
self.img = (self.img / 10).reshape(-1, 1)
|
|
|
|
self.img = (self.img / 10).reshape(-1, 1)
|
|
|
|
z += self.img
|
|
|
|
z += self.img
|
|
|
|
|
|
|
|
|
|
|
|
top_vert_arr = np.vstack(list(map(np.ravel, self.meshgrid))).T
|
|
|
|
vert_arr_tmp = np.vstack(list(map(np.ravel, self.meshgrid))).T
|
|
|
|
top_vert_arr = np.concatenate((top_vert_arr, z), axis=1)
|
|
|
|
# for top side
|
|
|
|
|
|
|
|
top_vert_arr = np.concatenate((vert_arr_tmp, z), axis=1)
|
|
|
|
top_vert_arr = top_vert_arr.reshape(self.height, self.width, 3)
|
|
|
|
top_vert_arr = top_vert_arr.reshape(self.height, self.width, 3)
|
|
|
|
|
|
|
|
# for bottom side
|
|
|
|
|
|
|
|
bottom_vert_arr = np.concatenate((vert_arr_tmp, z_cpy), axis=1)
|
|
|
|
|
|
|
|
bottom_vert_arr = bottom_vert_arr.reshape(self.height, self.width, 3)
|
|
|
|
|
|
|
|
|
|
|
|
count = 0
|
|
|
|
count = 0
|
|
|
|
vertices = []
|
|
|
|
vertices = []
|
|
|
|
faces = []
|
|
|
|
faces = []
|
|
|
|
|
|
|
|
|
|
|
|
#min_point = 0
|
|
|
|
|
|
|
|
#for i in range(self.height - 1):
|
|
|
|
|
|
|
|
# if top_vert_arr[i][0][2] <= bottom:
|
|
|
|
|
|
|
|
# min_point = i
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Add faces for the backside of the lithophane
|
|
|
|
|
|
|
|
#vec_side = (top_vert_arr[self.height-1][0][2] -
|
|
|
|
|
|
|
|
# top_vert_arr[min_point][0][2]) / (self.height - min_point)
|
|
|
|
|
|
|
|
bottom_vert_arr = np.copy(top_vert_arr)
|
|
|
|
|
|
|
|
self.engrave_text(bottom_vert_arr)
|
|
|
|
self.engrave_text(bottom_vert_arr)
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: code bellow is duplicate of the code in planar generation
|
|
|
|
# TODO: code bellow is duplicate of the code in planar generation
|
|
|
@ -556,8 +557,6 @@ class app:
|
|
|
|
|
|
|
|
|
|
|
|
# Horizontal side faces
|
|
|
|
# Horizontal side faces
|
|
|
|
for i in range(self.height - 1): # right
|
|
|
|
for i in range(self.height - 1): # right
|
|
|
|
#if (top_vert_arr[i][0][2] < bottom_vert_arr[i][0][2]):
|
|
|
|
|
|
|
|
# continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices.append([top_vert_arr[i][0]])
|
|
|
|
vertices.append([top_vert_arr[i][0]])
|
|
|
|
vertices.append([top_vert_arr[i+1][0]])
|
|
|
|
vertices.append([top_vert_arr[i+1][0]])
|
|
|
@ -565,11 +564,7 @@ class app:
|
|
|
|
vertices.append([bottom_vert_arr[i+1][0]])
|
|
|
|
vertices.append([bottom_vert_arr[i+1][0]])
|
|
|
|
|
|
|
|
|
|
|
|
count = self.append_faces(faces, count)
|
|
|
|
count = self.append_faces(faces, count)
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(self.height - 1): # left
|
|
|
|
|
|
|
|
max = self.width - 1
|
|
|
|
max = self.width - 1
|
|
|
|
#if (top_vert_arr[i][max][2] < bottom_vert_arr[i][max][2]):
|
|
|
|
|
|
|
|
# continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices.append([top_vert_arr[i+1][max]])
|
|
|
|
vertices.append([top_vert_arr[i+1][max]])
|
|
|
|
vertices.append([top_vert_arr[i][max]])
|
|
|
|
vertices.append([top_vert_arr[i][max]])
|
|
|
@ -579,9 +574,7 @@ class app:
|
|
|
|
count = self.append_faces(faces, count)
|
|
|
|
count = self.append_faces(faces, count)
|
|
|
|
|
|
|
|
|
|
|
|
# Vertical side faces
|
|
|
|
# Vertical side faces
|
|
|
|
for j in range(self.width - 1): # top
|
|
|
|
for j in range(self.width - 1):
|
|
|
|
#if (top_vert_arr[0][j][2] < bottom_vert_arr[0][j][2]):
|
|
|
|
|
|
|
|
# continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices.append([top_vert_arr[0][j+1]])
|
|
|
|
vertices.append([top_vert_arr[0][j+1]])
|
|
|
|
vertices.append([top_vert_arr[0][j]])
|
|
|
|
vertices.append([top_vert_arr[0][j]])
|
|
|
@ -589,11 +582,7 @@ class app:
|
|
|
|
vertices.append([bottom_vert_arr[0][j]])
|
|
|
|
vertices.append([bottom_vert_arr[0][j]])
|
|
|
|
|
|
|
|
|
|
|
|
count = self.append_faces(faces, count)
|
|
|
|
count = self.append_faces(faces, count)
|
|
|
|
|
|
|
|
|
|
|
|
for j in range(self.width - 1): # bottom
|
|
|
|
|
|
|
|
max = self.height - 1
|
|
|
|
max = self.height - 1
|
|
|
|
#if (top_vert_arr[max][j][2] < bottom_vert_arr[max][j][2]):
|
|
|
|
|
|
|
|
# continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vertices.append([top_vert_arr[max][j]])
|
|
|
|
vertices.append([top_vert_arr[max][j]])
|
|
|
|
vertices.append([top_vert_arr[max][j+1]])
|
|
|
|
vertices.append([top_vert_arr[max][j+1]])
|
|
|
|