|
|
@ -124,54 +124,62 @@ class fingerprint_app:
|
|
|
|
def parse_stl(self):
|
|
|
|
def parse_stl(self):
|
|
|
|
# Get stl filename
|
|
|
|
# Get stl filename
|
|
|
|
self.stl_path = self.output_file.rsplit('/', 1)[0] + '/'
|
|
|
|
self.stl_path = self.output_file.rsplit('/', 1)[0] + '/'
|
|
|
|
|
|
|
|
self.mode = self.args.stl[0]
|
|
|
|
|
|
|
|
|
|
|
|
# Get mode and model parameters
|
|
|
|
# Get mode and model parameters
|
|
|
|
if self.args.stl[0] == 'p':
|
|
|
|
if self.mode == 'p':
|
|
|
|
self.mode = "planar"
|
|
|
|
|
|
|
|
|
|
|
|
def_val = {"hl": 1.0, "hb": 0.2}
|
|
|
|
|
|
|
|
self.height_line = float(self.args.stl[1]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 1 else def_val.get("hl")
|
|
|
|
|
|
|
|
self.height_base = float(self.args.stl[2]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 2 else def_val.get("hb")
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: add default values for planar mode, not like this
|
|
|
|
|
|
|
|
if len(self.args.stl) < 3:
|
|
|
|
if len(self.args.stl) < 3:
|
|
|
|
self.height_line = 2
|
|
|
|
|
|
|
|
self.height_base = 10
|
|
|
|
|
|
|
|
log.print_message(
|
|
|
|
log.print_message(
|
|
|
|
"Warning: Too few arguments, using default values (10mm base, 2mm lines)")
|
|
|
|
"Warning: Too few arguments, using default values")
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.height_line = float(self.args.stl[1])
|
|
|
|
|
|
|
|
self.height_base = float(self.args.stl[2])
|
|
|
|
|
|
|
|
log.print_message("Base height:", self.height_base,
|
|
|
|
log.print_message("Base height:", self.height_base,
|
|
|
|
"mm, lines depth/height:", self.height_line, "mm")
|
|
|
|
"mm, lines depth/height:", self.height_line, "mm")
|
|
|
|
|
|
|
|
|
|
|
|
elif self.args.stl[0] == 'c':
|
|
|
|
elif self.mode == 'c':
|
|
|
|
self.mode = "curved"
|
|
|
|
|
|
|
|
|
|
|
|
def_val = {"hl": 0.2, "hb": 10.0,
|
|
|
|
|
|
|
|
"crx": 2, "cry": 4}
|
|
|
|
|
|
|
|
self.height_line = float(self.args.stl[1]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 1 else def_val.get("hl")
|
|
|
|
|
|
|
|
self.height_base = float(self.args.stl[2]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 2 else def_val.get("hb")
|
|
|
|
|
|
|
|
self.curv_rate_x = float(self.args.stl[3]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 3 else def_val.get("crx")
|
|
|
|
|
|
|
|
self.curv_rate_y = float(self.args.stl[4]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 4 else def_val.get("cry")
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: add default values for curved mode, not like this
|
|
|
|
|
|
|
|
if len(self.args.stl) < 5:
|
|
|
|
if len(self.args.stl) < 5:
|
|
|
|
self.height_line = 2
|
|
|
|
|
|
|
|
self.height_base = 10
|
|
|
|
|
|
|
|
self.curv_rate_x = 2
|
|
|
|
|
|
|
|
self.curv_rate_y = 6
|
|
|
|
|
|
|
|
log.print_message(
|
|
|
|
log.print_message(
|
|
|
|
"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")
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.height_line = float(self.args.stl[1])
|
|
|
|
|
|
|
|
self.height_base = float(self.args.stl[2])
|
|
|
|
|
|
|
|
self.curv_rate_x = float(self.args.stl[3])
|
|
|
|
|
|
|
|
self.curv_rate_y = float(self.args.stl[4])
|
|
|
|
|
|
|
|
log.print_message("Line height:", self.height_line, "mm, base height:", self.height_base,
|
|
|
|
log.print_message("Line height:", self.height_line, "mm, base height:", self.height_base,
|
|
|
|
"mm, x axis curvature:", self.curv_rate_x, ", y axis curvature:", self.curv_rate_y)
|
|
|
|
"mm, x axis curvature:", self.curv_rate_x, ", y axis curvature:", self.curv_rate_y)
|
|
|
|
elif self.args.stl[0] == 'm':
|
|
|
|
|
|
|
|
self.mode = "mapped"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: add default values for mapped mode, add finger model?
|
|
|
|
elif self.mode == 'm':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def_val = {"hl": 0.2, "it": 2,
|
|
|
|
|
|
|
|
"fx": 0, "fy": 0, "fz": 0}
|
|
|
|
|
|
|
|
self.height_line = float(self.args.stl[1]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 1 else def_val.get("hl")
|
|
|
|
|
|
|
|
self.iter = int(self.args.stl[2]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 2 else def_val.get("it")
|
|
|
|
|
|
|
|
self.finger_x = float(self.args.stl[3]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 3 else def_val.get("fx")
|
|
|
|
|
|
|
|
self.finger_y = float(self.args.stl[4]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 4 else def_val.get("fy")
|
|
|
|
|
|
|
|
self.finger_z = float(self.args.stl[5]) if len(
|
|
|
|
|
|
|
|
self.args.stl) > 5 else def_val.get("fz")
|
|
|
|
|
|
|
|
|
|
|
|
if len(self.args.stl) < 6:
|
|
|
|
if len(self.args.stl) < 6:
|
|
|
|
log.print_message(
|
|
|
|
log.print_message(
|
|
|
|
"Warning: Too few arguments, using default values")
|
|
|
|
"Warning: Too few arguments, using default values for mapped mode")
|
|
|
|
else:
|
|
|
|
log.print_message("Line height:", self.height_line, "mm, iterations:", self.iter,
|
|
|
|
self.height_line = float(self.args.stl[1])
|
|
|
|
", finger position:", self.finger_x, self.finger_y, self.finger_z)
|
|
|
|
self.iter = int(self.args.stl[2])
|
|
|
|
|
|
|
|
self.finger_x = float(self.args.stl[3])
|
|
|
|
|
|
|
|
self.finger_y = float(self.args.stl[4])
|
|
|
|
|
|
|
|
self.finger_z = float(self.args.stl[5])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
log.error_exit("Unrecognized generation mode")
|
|
|
|
log.error_exit("Unrecognized generation mode")
|
|
|
@ -264,13 +272,13 @@ class fingerprint_app:
|
|
|
|
log.print_message("Creating mesh")
|
|
|
|
log.print_message("Creating mesh")
|
|
|
|
|
|
|
|
|
|
|
|
# Create a mesh using one of two modes
|
|
|
|
# Create a mesh using one of two modes
|
|
|
|
if self.mode == "planar":
|
|
|
|
if self.mode == "p":
|
|
|
|
self.make_stl_planar()
|
|
|
|
self.make_stl_planar()
|
|
|
|
|
|
|
|
|
|
|
|
elif self.mode == "curved":
|
|
|
|
elif self.mode == "c":
|
|
|
|
self.make_stl_curved()
|
|
|
|
self.make_stl_curved()
|
|
|
|
|
|
|
|
|
|
|
|
elif self.mode == "mapped":
|
|
|
|
elif self.mode == "m":
|
|
|
|
self.make_stl_map()
|
|
|
|
self.make_stl_map()
|
|
|
|
|
|
|
|
|
|
|
|
plt.show()
|
|
|
|
plt.show()
|
|
|
@ -289,19 +297,19 @@ class fingerprint_app:
|
|
|
|
self.img = self.img / np.max(self.img) * 255
|
|
|
|
self.img = self.img / np.max(self.img) * 255
|
|
|
|
self.img = self.img.astype(np.uint8)
|
|
|
|
self.img = self.img.astype(np.uint8)
|
|
|
|
|
|
|
|
|
|
|
|
if self.mode == "planar":
|
|
|
|
if self.mode == "p":
|
|
|
|
if self.height_base <= 0:
|
|
|
|
if self.height_base <= 0:
|
|
|
|
log.error_exit("Depth of plate height must be positive")
|
|
|
|
log.error_exit("Depth of plate height must be positive")
|
|
|
|
|
|
|
|
|
|
|
|
if self.height_line + self.height_base <= 0:
|
|
|
|
if self.height_line + self.height_base <= 0:
|
|
|
|
log.error_exit("Line depth must be less than plate thickness")
|
|
|
|
log.error_exit("Line depth must be less than plate thickness")
|
|
|
|
|
|
|
|
|
|
|
|
if self.mode == "curved":
|
|
|
|
if self.mode == "c":
|
|
|
|
# Don't need to check curvature, check only heights
|
|
|
|
# Don't need to check curvature, check only heights
|
|
|
|
if self.height_base <= 0 or self.height_line <= 0:
|
|
|
|
if self.height_base <= 0 or self.height_line <= 0:
|
|
|
|
log.error_exit("Base and line height must both be positive")
|
|
|
|
log.error_exit("Base and line height must both be positive")
|
|
|
|
|
|
|
|
|
|
|
|
if self.mode == "mapped":
|
|
|
|
if self.mode == "m":
|
|
|
|
if self.height_line <= 0:
|
|
|
|
if self.height_line <= 0:
|
|
|
|
log.error_exit("Line height must be positive")
|
|
|
|
log.error_exit("Line height must be positive")
|
|
|
|
if self.iter < 0:
|
|
|
|
if self.iter < 0:
|
|
|
@ -369,22 +377,22 @@ class fingerprint_app:
|
|
|
|
param_list.append(str(self.height_base))
|
|
|
|
param_list.append(str(self.height_base))
|
|
|
|
|
|
|
|
|
|
|
|
# add parameters specific to the model type
|
|
|
|
# add parameters specific to the model type
|
|
|
|
if self.mode == "curved":
|
|
|
|
if self.mode == "c":
|
|
|
|
param_list.append(str(self.curv_rate_x))
|
|
|
|
param_list.append(str(self.curv_rate_x))
|
|
|
|
param_list.append(str(self.curv_rate_y))
|
|
|
|
param_list.append(str(self.curv_rate_y))
|
|
|
|
|
|
|
|
|
|
|
|
if self.mode == "mapped":
|
|
|
|
if self.mode == "m":
|
|
|
|
param_list.append(str(self.height_line))
|
|
|
|
param_list.append(str(self.height_line))
|
|
|
|
param_list.append(str(self.iter))
|
|
|
|
param_list.append(str(self.iter))
|
|
|
|
param_list.append(str(self.finger_x))
|
|
|
|
param_list.append(str(self.finger_x))
|
|
|
|
param_list.append(str(self.finger_y))
|
|
|
|
param_list.append(str(self.finger_y))
|
|
|
|
param_list.append(str(self.finger_z))
|
|
|
|
param_list.append(str(self.finger_z))
|
|
|
|
|
|
|
|
|
|
|
|
if self.mode == "planar":
|
|
|
|
if self.mode == "p":
|
|
|
|
param_list.append("P")
|
|
|
|
param_list.append("P")
|
|
|
|
elif self.mode == "curved":
|
|
|
|
elif self.mode == "c":
|
|
|
|
param_list.append("C")
|
|
|
|
param_list.append("C")
|
|
|
|
elif self.mode == "mapped":
|
|
|
|
elif self.mode == "m":
|
|
|
|
param_list.append("M")
|
|
|
|
param_list.append("M")
|
|
|
|
|
|
|
|
|
|
|
|
if self.args.mirror:
|
|
|
|
if self.args.mirror:
|
|
|
@ -451,10 +459,10 @@ class fingerprint_app:
|
|
|
|
# add the bottom array
|
|
|
|
# add the bottom array
|
|
|
|
OFFSET = 0.01
|
|
|
|
OFFSET = 0.01
|
|
|
|
for i in range(self.height):
|
|
|
|
for i in range(self.height):
|
|
|
|
if self.mode == "planar":
|
|
|
|
if self.mode == "p":
|
|
|
|
for j in range(self.width):
|
|
|
|
for j in range(self.width):
|
|
|
|
bottom_vert_arr[i][j][2] = data[i][j][0]
|
|
|
|
bottom_vert_arr[i][j][2] = data[i][j][0]
|
|
|
|
elif self.mode == "curved":
|
|
|
|
elif self.mode == "c":
|
|
|
|
for j in range(self.width):
|
|
|
|
for j in range(self.width):
|
|
|
|
bottom_vert_arr[i][j][2] += data[i][j][0]
|
|
|
|
bottom_vert_arr[i][j][2] += data[i][j][0]
|
|
|
|
if (bottom_vert_arr[i][j][2] < (top_vert_arr[i][0][2])-OFFSET):
|
|
|
|
if (bottom_vert_arr[i][j][2] < (top_vert_arr[i][0][2])-OFFSET):
|
|
|
@ -723,13 +731,11 @@ class fingerprint_app:
|
|
|
|
|
|
|
|
|
|
|
|
# For logging progress
|
|
|
|
# For logging progress
|
|
|
|
c = 0
|
|
|
|
c = 0
|
|
|
|
u = 0
|
|
|
|
|
|
|
|
for k, vertice in enumerate(vertices):
|
|
|
|
for k, vertice in enumerate(vertices):
|
|
|
|
# Skip vertices under plane xy
|
|
|
|
# Skip vertices under plane xy
|
|
|
|
# also skip vertices under the fingerprint image,
|
|
|
|
# also skip vertices under the fingerprint image,
|
|
|
|
# they are all unused
|
|
|
|
# they are all unused
|
|
|
|
if vertice[2] < 0 or vertice[1] > self.height * px2mm:
|
|
|
|
if vertice[2] < 0 or vertice[1] > self.height * px2mm:
|
|
|
|
u += 1
|
|
|
|
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# This is the easiest way to avoid indexing errors
|
|
|
|
# This is the easiest way to avoid indexing errors
|
|
|
@ -753,7 +759,6 @@ class fingerprint_app:
|
|
|
|
|
|
|
|
|
|
|
|
self.stl_model = trimesh.Trimesh(vertices, faces)
|
|
|
|
self.stl_model = trimesh.Trimesh(vertices, faces)
|
|
|
|
log.print_message("Carving finger finished")
|
|
|
|
log.print_message("Carving finger finished")
|
|
|
|
print("Unused vertices: " + str(u))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def save_stl(self):
|
|
|
|
def save_stl(self):
|
|
|
|
'''Save final mesh to stl file.
|
|
|
|
'''Save final mesh to stl file.
|
|
|
@ -762,7 +767,7 @@ class fingerprint_app:
|
|
|
|
# Create output file name, save it and write header with file info
|
|
|
|
# Create output file name, save it and write header with file info
|
|
|
|
self.stl_filename = self.output_file.split(
|
|
|
|
self.stl_filename = self.output_file.split(
|
|
|
|
".")[0] + "_" + self.id + ".stl"
|
|
|
|
".")[0] + "_" + self.id + ".stl"
|
|
|
|
if (self.mode == "mapped"):
|
|
|
|
if (self.mode == "m"):
|
|
|
|
self.stl_model.export(file_obj=self.stl_filename)
|
|
|
|
self.stl_model.export(file_obj=self.stl_filename)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.stl_model.save(self.stl_filename)
|
|
|
|
self.stl_model.save(self.stl_filename)
|
|
|
|