def test_fill_from_CSS(filepath, offset, is_reverse_img=True): pe = pathengine.pathEngine() #1.find contours from slice pe.generate_contours_from_img(filepath, is_reverse_img) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) #2.filling each connected region dist_th = abs( offset) * 1.1 # contour distance threshold between adjacent layers iB = 0 for boundary in group_boundary.values(): print("Region {}: has {} boundry contours.".format(iB, len(boundary))) spiral = pe.fill_spiral_in_connected_region(boundary, offset) spiral = pe.smooth_curve_by_savgol(spiral, 3, 1) pathengine.suPath2D.draw_line(spiral, pe.im, [100, 255, 100], 1) #debug: draw all spiral #id_sp = 0 #kappa, smooth = css.compute_curve_css(spiral, 4) #css_idx = css.find_css_point(kappa) #for i in css_idx: #cv2.circle(pe.im, tuple(spiral[i].astype(int)), 2, (255,255,0), -1) iB += 1 cv2.imwrite("r:/fig4-c.png", pe.im) cv2.imshow("Art", pe.im) cv2.waitKey(0)
def fill(self): try: i = self.sl.value() self.message("Show slice {}.".format(i + 1), False) curdir = os.getcwd() filepath = self.out_path % i offset = self.conf.get("infill_offset") line_width = 1 # int(abs(offset)/2) pe = pathengine.pathEngine() pe.generate_contours_from_img(filepath, True) pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_contour = pe.get_contours_from_each_connected_region( contour_tree, '0') # draw boundaries ################################# # Generate N color list ################################# def generate_RGB_list(N): import colorsys HSV_tuples = [(x * 1.0 / N, 0.8, 0.9) for x in range(N)] RGB_tuples = map(lambda x: colorsys.hsv_to_rgb(*x), HSV_tuples) rgb_list = tuple(RGB_tuples) return np.array(rgb_list) * 255 N = 50 colors = generate_RGB_list(N) bg_img = pe.im.copy() bg_img = np.full(bg_img.shape, 255, dtype=np.uint8) for boundary in group_contour.values(): spiral = mkspiral.spiral(pe, boundary, offset) pathengine.suPath2D.draw_line( spiral, bg_img, colors[0], line_width) # for show cv2.imwrite(filepath, bg_img) tex1 = cv2.cvtColor(bg_img, cv2.COLOR_BGR2RGBA) v1 = gl.GLImageItem(tex1) v1.translate(0, 0, i * self.mesh_info.layer_thickness) self.view_slice.items = [] self.view_slice.addItem(v1) except Exception as e: self.message(str(e)) return
def gen_continuous_path_with_constraint(ms_info, tmp_slice_path, collision_dist_xy=30, collision_dist_z=30, offset=-4): m = ms_info N = m.get_layers() z_list = m.get_z_list() #slicing remove_files(tmp_slice_path) curdir = os.getcwd() out_path = tmp_slice_path + "/slice-%d.png" real_pixel_size, real_pixel_size, gcode_minx, gcode_miny = stl2pngfunc.stl2png( m.path, z_list, m.image_width, m.image_height, out_path, m.border_size, func=lambda i: print("slicing layer {}/{}".format(i + 1, N))) #print sequence R = [] #R = {r_ij} S = [] #sequence with [[i,j]......] pe = pathengine.pathEngine() for i in range(N): img_file = out_path % i rs = get_region_boundary_from_img(img_file, pe, True) R.append(rs) d = RDqueue(R) #d = di = dj = deque() r, i, j = d.get_end() while d.size() != 0: if (i < N - 1) and (not is_interference_xyz( ms_info, d, i, j, collision_dist_xy, collision_dist_z)): S.append([i, j]) d.remove_item(i, j) i = i + 1 rs, js = find_surpported_regions(d, r, i, -6) if js == []: r, i, j = d.get_end() continue else: j = js[0] r = rs[0] for idx in range(1, len(js)): d.move_to_end(i, idx) if i == (N - 1): # reach the top if not is_interference_xyz(ms_info, d, i, j, collision_dist_xy, collision_dist_z): S.append([i, j]) d.remove_item(i, j) r, i, j = d.get_end() else: r_next, i_next, j_next = d.get_end() if [i, j] == [ i_next, j_next ]: #the extruder goes back and the region is not be appended S.append([i, j]) d.remove_item(i, j) r_next, i_next, j_next = d.get_end() else: if i <= i_next: # The new region is not lower than current, S.append([i, j]) # so the nozzle doesn't need to go down. d.remove_item(i, j) r = r_next i = i_next j = j_next # generate spiral and connect them # todo: connect path on the nearest point d = RDqueue(R) path = [] Z = 0.0 z_list[-1] = z_list[-2] + m.layer_thickness for i in range(0, len(S)): iLayer = S[i][0] r = d.get_item(iLayer, S[i][1]) cs = spiral(pe, r, offset) * ms_info.get_pixel_size() #transformation to 3d vector Z = z_list[iLayer] z = [Z] * len(cs) z = np.array(z).reshape([len(z), 1]) if i == 0: path = np.hstack([cs, z]) else: cs = np.hstack([cs, z]) path = np.vstack([path, cs]) #if i== 0: #path = np.hstack([cs,z]) #else: #if iLayer == 1: #z += ms_info.first_layer_thickness #elif iLayer > 1: #z += ((iLayer-1) * ms_info.layer_thickness + ms_info.first_layer_thickness) #cs = np.hstack([cs,z]) #path = np.vstack([path,cs]) return path
out_path = os.path.join(curdir, "images/slice-%d.png") real_pixel_size, real_pixel_size, gcode_minx, gcode_miny = stl2pngfunc.stl2png( file_path, N, m.image_width, m.image_height, out_path, func=lambda i: print("slicing layer {}/{}".format(i + 1, N))) print('Slicing mesh into ' + out_path) # algorithm dq = deque() pe = pathengine.pathEngine() def get_region_boundary_from_img(img_path, pe, is_reverse=False): ''' @image_path is an obsolute file path @pe is a reference of patheEngine object @is_reverse is paramether for generate_contours_from_img @return a list, each element represents a group of boundaries of a connected region. ''' pe.generate_contours_from_img(img_path, is_reverse) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') #closed region cs_region_list = []
def test_fill_from_CSS(filepath, offset, is_reverse_img=True): pe = pathengine.pathEngine() def dfs_draw_contours_in_pocket(i, nodes, iso_contours_2D, spirals, offset): global colors global iColor node = nodes[i] msg = '{} make spiral {}'.format(i + 1, np.asarray(node.data) + 1) print(msg) cs = [] for ii in node.data: cs.append(iso_contours_2D[ii]) c = pathengine.suPath2D.resample_curve_by_equal_dist( iso_contours_2D[ii], 4) c = np.asarray(c) c = np.vstack((c, c[0])) pathengine.suPath2D.draw_line(c, pe.im, colors[iColor], 1) iColor += 1 print("iColor={}".format(iColor)) #spirals[i] = pe.build_spiral_for_pocket(cs) if (len(node.next) > 0): for ic in node.next: dfs_draw_contours_in_pocket(ic, nodes, iso_contours_2D, spirals, offset) return #1.find contours from slice pe.generate_contours_from_img(filepath, is_reverse_img) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) #2.filling each connected region dist_th = abs( offset) * 1.1 # contour distance threshold between adjacent layers iB = 0 for boundary in group_boundary.values(): print("Region {}: has {} boundry contours.".format(iB, len(boundary))) iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) graph.to_Mathematica("") if not graph.is_connected(): print("not connected") ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset * 1.2)) if (ret): print("re-connect...") graph.to_Mathematica("") # generate a minimum-weight spanning tree graph.to_reverse_delete_MST() graph.to_Mathematica("") # generate a minimum-weight spanning tree pocket_graph = graph.gen_pockets_graph() pocket_graph.to_Mathematica("") dfs_draw_contours_in_pocket(0, pocket_graph.nodes, iso_contours_2D, {}, offset) draw_iso_contour_id(pe, iso_contours_2D) #show CSS points #for c in iso_contours_2D: #draw_css_on_contour(pe, c, 1) iB += 1 cv2.imwrite("r:/im1.png", pe.im) cv2.imshow("Art", pe.im) cv2.waitKey(0)
def gen_continous_path(ms_info, tmp_slice_path, slice_layers, collision_dist=3, offset=-4): dist_th = collision_dist N = slice_layers m = ms_info m.set_layers(N) #slicing remove_files(tmp_slice_path) curdir = os.getcwd() out_path = tmp_slice_path + "/slice-%d.png" real_pixel_size, real_pixel_size, gcode_minx, gcode_miny = stl2pngfunc.stl2png( ms_info.path, N, m.image_width, m.image_height, out_path, func=lambda i: print("slicing layer {}/{}".format(i + 1, N))) #print sequence R = [] #R = {r_ij} S = [] #sequence with [[i,j]......] pe = pathengine.pathEngine() for i in range(N): img_file = out_path % i rs = get_region_boundary_from_img(img_file, pe, True) for r in rs: for c in r: print(c.shape) R.append(rs) d = RDqueue(R) #d = di = dj = deque() r, i, j = d.get_end() while d.size() != 0: if (i < N - 1) and (not is_interference(d, i, j, dist_th)): S.append([i, j]) d.remove_item(i, j) i = i + 1 r, j = find_surpported_region_in_layer(d, r, i, -6) if j == -1: r, i, j = d.get_end() continue if i == (N - 1): # reach the top if not is_interference(d, i, j, dist_th): S.append([i, j]) d.remove_item(i, j) r, i, j = d.get_end() else: r_next, i_next, j_next = d.get_end() if [i, j] == [ i_next, j_next ]: #the nozzle goes back and the region is not be appended S.append([i, j]) d.remove_item(i, j) r_next, i_next, j_next = d.get_end() else: if i <= i_next: # The new region is not lower than current, S.append([i, j]) # so the nozzle doesn't need to go down. d.remove_item(i, j) r = r_next i = i_next j = j_next # generate spiral and connect them d = RDqueue(R) path = [] Z = 0.0 for i in range(0, len(S) - 1): iLayer = S[i][0] r = d.get_item(iLayer, S[i][1]) cs = spiral(pe, r, offset) * ms_info.get_pixel_size() #transformation to 3d vector z = [Z] * len(cs) z = np.array(z).reshape([len(z), 1]) if i == 0: path = np.hstack([cs, z]) else: if iLayer == 1: z += ms_info.first_layer_thickness elif iLayer > 1: z += ((iLayer - 1) * ms_info.layer_thickness + ms_info.first_layer_thickness) cs = np.hstack([cs, z]) path = np.vstack([path, cs]) return path
def test_pocket_spiral(filepath, offset=-14, reverseImage=True): path2d = pathengine.suPath2D() line_width = 1 #int(abs(offset)/2) pe = pathengine.pathEngine() pe.generate_contours_from_img(filepath, reverseImage) pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) contour_tree = pe.convert_hiearchy_to_PyPolyTree() path2d.group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') ## Build a init graph from boundaries # contour distance threshold between adjacent layers dist_th = abs(offset) * 1.05 iB = 0 for boundary in path2d.group_boundary.values(): msg = "Region {}: has {} boundry contours.".format(iB, len(boundary)) print(msg) iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) # init contour graph for each region num_contours = 0 iso_contours_2D = [] map_ij = [] for i in range(len(iso_contours)): for j in range(len(iso_contours[i])): # resample and convert to np.array iso_contours[i][j] = pe.resample_curve_by_equal_dist( iso_contours[i][j], abs(offset) / 4) if (i == 0): iso_contours_2D.append(np.flip(iso_contours[i][j], 0)) else: iso_contours_2D.append(iso_contours[i][j]) map_ij.append([i, j]) num_contours += 1 # @R is the relationship matrix R = np.zeros((num_contours, num_contours)).astype(int) i = 0 for cs in iso_contours[: -1]: # for each group contour[i], where i*offset reprents the distance from boundaries j1 = 0 for c1 in cs: c1_id = path2d.get_contour_id(i, j1, iso_contours) j2 = 0 for c2 in iso_contours[i + 1]: dist = scid.cdist(c1, c2, 'euclidean') min_dist = np.min(dist) #print(dist) if (min_dist < dist_th): c2_id = path2d.get_contour_id(i + 1, j2, iso_contours) R[c1_id][c2_id] = 1 j2 += 1 j1 += 1 i += 1 #visualize graph = suGraph.suGraph() #graph.init_from_matrix(R) #graph.simplify(map_ij) pockets = graph.classify_nodes_by_type(R, map_ij) #graph.to_Mathematica("") print(pockets) # gen spiral for each pocket spirals = [] for p in pockets: cs = [] for c_id in p: cs.append(iso_contours_2D[c_id]) if (c_id == 37): pe.path2d.draw_text(str(c_id + 1), iso_contours_2D[c_id][0], pe.im) if (len(cs) != 0): spiral = pe.build_spiral_for_pocket(cs) spirals.append(spiral) for p_id in range(len(pockets)): #node = graph.get_node(where_pocket_id = p_id) #if node.is_typeII(): #connect_spiral(node_pre.pocket_id, p_id) #connect_spiral(node_next.pocket_id, p_id) if len(pockets[p_id]) == 1: color = [0, 0, 255] else: color = [255, 0, 0] path2d.draw_line(spirals[p_id], pe.im, color, 1) graph.to_Mathematica("") path2d.group_isocontours.append(iso_contours) path2d.group_isocontours_2D.append(iso_contours_2D) path2d.group_relationship_matrix.append(R) iB += 1 graph.connect_node_by_spiral(spirals) gray = cv2.cvtColor(pe.im, cv2.COLOR_BGR2GRAY) pe.im[np.where((pe.im == [0, 0, 0]).all(axis=2))] = [255, 255, 255] cv2.imshow("Art", pe.im) cv2.waitKey(0)
def test_segment_contours_in_region(filepath): path2d = pathengine.suPath2D() offset = -14 line_width = 1 #int(abs(offset)/2) pe = pathengine.pathEngine() pe.generate_contours_from_img(filepath, True) pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) contour_tree = pe.convert_hiearchy_to_PyPolyTree() path2d.group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') color = (255, 0, 0) ## Build a init graph from boundaries # distance threshold between two adjacent layers dist_th = abs(offset) * 1.2 iB = 0 for boundary in path2d.group_boundary.values(): msg = "Region {}: has {} boundry contours.".format(iB, len(boundary)) print(msg) iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) # init contour graph for each region num_contours = 0 iso_contours_2D = [] for i in range(len(iso_contours)): for j in range(len(iso_contours[i])): # resample and convert to np.array iso_contours[i][j] = pe.resample_curve_by_equal_dist( iso_contours[i][j], abs(offset / 2)) iso_contours_2D.append(iso_contours[i][j]) num_contours += 1 # @R is the relationship matrix R = np.zeros((num_contours, num_contours)).astype(int) # @input: iso_contours c_{i,j} i = 0 for cs in iso_contours[: -1]: # for each group contour[i], where i*offset reprents the distance from boundaries j1 = 0 for c1 in cs: c1_id = path2d.get_contour_id(i, j1, iso_contours) pathengine.suPath2D.draw_line(np.vstack([c1, c1[0]]), pe.im, color, 1, 2) pathengine.suPath2D.draw_text(str(c1_id + 1), c1[0], pe.im, (0, 0, 255)) j2 = 0 for c2 in iso_contours[i + 1]: dist = scid.cdist(c1, c2, 'euclidean') min_dist = np.min(dist) #print(dist) if (min_dist < dist_th): c2_id = path2d.get_contour_id(i + 1, j2, iso_contours) R[c1_id][c2_id] = 1 #debug: get indexes of two closest points gId = np.argmin(dist) pid_c1 = int(gId / dist.shape[1]) pid_c2 = gId - dist.shape[1] * pid_c1 pathengine.suPath2D.draw_line( np.asarray([c1[pid_c1], c2[pid_c2]]), pe.im, (0, 0, 255), 1, 0) j2 += 1 j1 += 1 i += 1 #visualize graph = suGraph.suGraph() #graph.init_from_matrix(R) pockets = graph.classify_nodes_by_type(R) N = len(pockets) colors = path2d.generate_RGB_list(N) p_id = 0 for p in pockets: print(np.array(p) + 1) for idx in p: pathengine.suPath2D.draw_line( np.vstack([iso_contours_2D[idx], iso_contours_2D[idx][0]]), pe.im, colors[p_id], 2, 4) p_id += 1 path2d.group_isocontours.append(iso_contours) path2d.group_isocontours_2D.append(iso_contours_2D) path2d.group_relationship_matrix.append(R) iB += 1 graph.to_Mathematica("") gray = cv2.cvtColor(pe.im, cv2.COLOR_BGR2GRAY) #ret, mask = cv2.threshold(gray, 1, 255,cv2.THRESH_BINARY) pe.im[np.where((pe.im == [0, 0, 0]).all(axis=2))] = [255, 255, 255] cv2.imwrite("d:/tmp.png", pe.im) cv2.imshow("Art", pe.im) cv2.waitKey(0)
def test_fill_from_CSS(filepath, offset, is_reverse_img=True): pe = pathengine.pathEngine() def fill_spiral_in_connected_region(boundary): print("Region {}: has {} boundry contours.".format(iB, len(boundary))) iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) # init contour graph for iso contour by a distance relationaship matrix iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) graph.to_Mathematica("") if not graph.is_connected(): print("not connected") ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset * 1.2)) if (ret): print("re-connect...") graph.to_Mathematica("") # generate a minimum-weight spanning tree graph.to_reverse_delete_MST() graph.to_Mathematica("") # generate a minimum-weight spanning tree pocket_graph = graph.gen_pockets_graph() pocket_graph.to_Mathematica("") # generate spiral for each pockets # deep first search spirals = {} pe.dfs_connect_path_from_bottom(0, pocket_graph.nodes, iso_contours_2D, spirals, offset) return spirals[0] #1.find contours from slice pe.generate_contours_from_img(filepath, is_reverse_img) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) #2.filling each connected region dist_th = abs( offset) * 1.1 # contour distance threshold between adjacent layers iB = 0 for boundary in group_boundary.values(): spiral = fill_spiral_in_connected_region(boundary) #print("Region {}: has {} boundry contours.".format(iB, len(boundary)) ) #iso_contours = pe.fill_closed_region_with_iso_contours(boundary, offset) ## init contour graph for iso contour by a distance relationaship matrix #iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) #graph.to_Mathematica("") #if not graph.is_connected(): #print("not connected") #ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset * 1.2)) #if(ret): #print("re-connect...") #graph.to_Mathematica("") ## generate a minimum-weight spanning tree #graph.to_reverse_delete_MST() #graph.to_Mathematica("") ## generate a minimum-weight spanning tree #pocket_graph = graph.gen_pockets_graph() #pocket_graph.to_Mathematica("") ## generate spiral for each pockets ## deep first search #spirals = {} #pe.dfs_connect_path_from_bottom(0, pocket_graph.nodes, iso_contours_2D, spirals, offset) ##test #for l in iso_contours_2D: #pathengine.suPath2D.draw_line(l, pe.im, [0,0,255],1) ##test #spirals[0] = pe.smooth_curve_by_savgol(spirals[0], 3, 1) pathengine.suPath2D.draw_line(spiral, pe.im, [100, 255, 100], 1) #id_sp = 0 #kappa, smooth = css.compute_curve_css(spirals[id_sp], 4) #css_idx = css.find_css_point(kappa) #for i in css_idx: #cv2.circle(pe.im, tuple(spirals[id_sp][i].astype(int)), 2, (255,255,0), -1) iB += 1 cv2.imshow("Art", pe.im) cv2.waitKey(0)
def test_filling_with_continues_spiral(filepath, offset=-14, reverseImage=True): path2d = pathengine.suPath2D() line_width = 1 #int(abs(offset)/2) pe = pathengine.pathEngine() pe.generate_contours_from_img(filepath, reverseImage) pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) contour_tree = pe.convert_hiearchy_to_PyPolyTree() path2d.group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') iB = 0 for boundary in path2d.group_boundary.values(): msg = "Region {}: has {} boundry contours.".format(iB, len(boundary)) print(msg) #pathengine.suPath2D.convto_cw(boundary) iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) # init contour graph for iso contour by a distance matrix num_contours = 0 iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) graph.to_Mathematica("") if not graph.is_connected(): print("not connected") ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset * 1.2)) if (ret): print("re-connect...") graph.to_Mathematica("") # generate a minimum-weight spanning tree graph.to_reverse_delete_MST() graph.to_Mathematica("") # generate a minimum-weight spanning tree pocket_graph = graph.gen_pockets_graph() pocket_graph.to_Mathematica("") # generate spiral for each pockets # deep first search spirals = {} def dfs_connect_path_from_bottom(i, nodes, iso_contours_2D, spirals, offset): node = nodes[i] msg = '{} make spiral {}'.format(i + 1, np.asarray(node.data) + 1) print(msg) cs = [] for ii in node.data: cs.append(iso_contours_2D[ii]) spirals[i] = pe.build_spiral_for_pocket(cs) #path2d.draw_line(spirals[i], pe.im, [255,255,0],1) if (len(node.next) > 0): for ic in node.next: dfs_connect_path_from_bottom(ic, nodes, iso_contours_2D, spirals, offset) if (ic == 22 and i == 18): print("debug") if (len(spirals[ic]) / len(spirals[i]) > 2): spirals[i] = pe.test_connect_two_pockets( spirals[ic], spirals[i], abs(offset)) msg = '{} insert {}'.format(ic + 1, i + 1) print(msg) else: spirals[i] = pe.test_connect_two_pockets( spirals[i], spirals[ic], abs(offset)) msg = '{} insert {}'.format(i + 1, ic + 1) print(msg) if (i == 6 and ic == 7): msg = "{}: {}, {}: {}".format(i, len(spirals[i]), ic, len(spirals[ic])) print(msg) return dfs_connect_path_from_bottom(0, pocket_graph.nodes, iso_contours_2D, spirals, offset) #cs = [] #for i in node.data: #cs.append(iso_contours_2D[i]) #if(len(cs) !=0): #spiral = pe.build_spiral_for_pocket(cs) #test verts = [] cs = [] ll = [35, 37, 39] #k = 0 #for jj in ll: ##path2d.draw_line(iso_contours_2D[jj], pe.im, colors[k],1) #cs.append(iso_contours_2D[jj-1]) ##k += 1 #for p in iso_contours_2D[jj-1]: #verts.append(p) #verts = np.array(verts).reshape([len(verts),2]) #draw_pca_for_pocket(spirals[9]) #cv2.circle(pe.im, tuple(spirals[0][-1].astype(int)), 5, (0,0,255)) #il = 0 #for l in ll: #path2d.draw_line(spirals.get(l-1), pe.im, colors[il],1) #msg = "{}: {}".format(l-1, len(spirals[l-1])) #print(msg) #il+=1 for i in range(len(iso_contours_2D)): c = () if (pathengine.suPath2D.ccw(iso_contours_2D[i])): c = (255, 0, 0) #ccw else: c = (0, 0, 255) #pathengine.suPath2D.draw_line(iso_contours_2D[i], pe.im, c ,1) ##cv2.circle(pe.im, tuple(iso_contours_2D[i][0].astype(int)), 5, (255,255,0), -1) ##cv2.circle(pe.im, tuple(iso_contours_2D[i][5].astype(int)), 5, (0,0,255), -1) #pathengine.suPath2D.draw_text(str(i + 1), iso_contours_2D[i][0], pe.im) spirals[0] = pe.smooth_curve_by_savgol(spirals[0], 3, 1) pathengine.suPath2D.draw_line(spirals[0], pe.im, [100, 255, 100], 1) #spiral id #for i in range(len(spirals)): #pathengine.suPath2D.draw_text(str(i + 1), spirals[i][0], pe.im) kappa, smooth = css.compute_curve_css(spirals[22], 2) css_idx = css.find_css_point(kappa) for i in css_idx: cv2.circle(pe.im, tuple(spirals[22][i].astype(int)), 2, (255, 255, 0), -1) id_sp = 0 kappa, smooth = css.compute_curve_css(spirals[id_sp], 4) css_idx = css.find_css_point(kappa) for i in css_idx: cv2.circle(pe.im, tuple(spirals[id_sp][i].astype(int)), 2, (255, 255, 0), -1) pathengine.suPath2D.draw_line(spirals[22], pe.im, [0, 0, 255], 1) #pathengine.suPath2D.draw_line(iso_contours_2D[36], pe.im, [0,0,255] ,1) #path2d.draw_line(spirals.get(3), pe.im, [0,0,255],1) #path2d.draw_line(spirals.get(1), pe.im, [255,0,20],1) #path2d.draw_line(spirals.get(2), pe.im, [0,255,33],1) #colors = pathengine.suPath2D.generate_RGB_list(len(spirals)) #for i in range(len(spirals)): #path2d.draw_line(spirals[i], pe.im, colors[i],1) #sptmp = pe.build_spiral_for_pocket(cs) #path2d.draw_line(sptmp, pe.im, [0,0,255],1) #path2d.draw_line(spirals.get(9), pe.im, [0,0,255],1) #path2d.draw_line(spirals.get(5), pe.im, [0,255,0],1) #path2d.draw_line(spirals[7], pe.im, [255,255,0],1) iB += 1 #graph.connect_node_by_spiral(spirals) gray = cv2.cvtColor(pe.im, cv2.COLOR_BGR2GRAY) pe.im[np.where((pe.im == [0, 0, 0]).all(axis=2))] = [255, 255, 255] cv2.imwrite("d:/tmp.png", pe.im) cv2.imshow("Art", pe.im) cv2.waitKey(0)
def test_fill_from_CSS(filepath, offset, is_reverse_img=True): pe = pathengine.pathEngine() line_width = 2 #abs(offset) def fill_spiral_in_connected_region(boundary): print("Region {}: has {} boundry contours.".format(iB, len(boundary)) ) iso_contours = pe.fill_closed_region_with_iso_contours(boundary, offset) # init contour graph for iso contour by a distance relationaship matrix iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) graph.to_Mathematica("") # draw iso contours for test im = pe.im for ic_1 in iso_contours_2D: contour = np.array(ic_1) pathengine.suPath2D.draw_line(contour, im, [255,0,0],1) # cv2.imshow("iso_contours_2d", im) # cv2.waitKey(0) if not graph.is_connected(): deta = 0 print("not connected") ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset*2)) if ret: print("re-connect...") graph.to_Mathematica("") # # draw iso contours for test # for ic_1 in iso_contours[:-1]: # for ic_2 in ic_1: # contour = np.array(ic_2) # pathengine.suPath2D.draw_line(contour, pe.im, [255,0,0],1) # cv2.imshow("iso_contours", pe.im) # cv2.waitKey(0) # generate a minimum-weight spanning tree graph.to_reverse_delete_MST() graph.to_Mathematica("") # generate a minimum-weight spanning tree pocket_graph = graph.gen_pockets_graph() pocket_graph.to_Mathematica("") # generate spiral for each pockets # deep first search spirals = {} pe.dfs_connect_path_from_bottom(0, pocket_graph.nodes, iso_contours_2D, spirals, offset) return spirals[0] #1.find contours from slice pe.generate_contours_from_img(filepath, is_reverse_img) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_boundary = pe.get_contours_from_each_connected_region(contour_tree, '0') pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) sm_im = pe.im.copy() pe_cov_im = pe.im.copy() sm_cov_im = pe.im.copy() #2.filling each connected region iB = 0 for boundary in group_boundary.values(): if (len(boundary) <= 2): continue spiral = fill_spiral_in_connected_region(boundary) pathengine.suPath2D.draw_line(spiral, pe.im, [100,255,100], line_width) pathengine.suPath2D.draw_line(spiral, pe_cov_im, [100,255,100], abs(offset)) cv2.circle(pe.im, tuple(spiral[-1].astype(int)), abs(offset), (255,0,0), -1) cv2.circle(pe.im, tuple(spiral[0].astype(int)), abs(offset), (0,0,255), -1) # Resample a curve by Roy's method spiral_smooth = pathengine.suPath2D.resample_curve_by_equal_dist(spiral, abs(offset)) # # Savitzky-Golay smoother inter_size = int(abs(offset)) if inter_size % 2 == 0: inter_size += 1 if inter_size < 5: inter_size = 5 poly_order = 3 spiral_smooth = pe.smooth_curve_by_savgol(spiral_smooth, inter_size, poly_order) # Smooth by affine transforms # spiral_smooth, _, _, _, _ = css.smooth_curve(spiral_smooth, 2) pathengine.suPath2D.draw_line(spiral_smooth, sm_im, [100,255,100], line_width) pathengine.suPath2D.draw_line(spiral_smooth, sm_cov_im, [100,255,100], abs(offset)) cv2.circle(sm_im, tuple(spiral_smooth[-1].astype(int)), abs(offset), (255,0,0), -1) cv2.circle(sm_im, tuple(spiral_smooth[0].astype(int)), abs(offset), (0,0,255), -1) # test boundary # print(len(boundary)) # im_color = pe.im.copy() # im_color = cv2.drawContours(im_color, boundary, -1, (0,255,0), 10) # im_color = cv2.resize(im_color, (1000,1000)) # cv2.imshow("contours", im_color) # cv2.waitKey(0) # print("Region {}: has {} boundry contours.".format(iB, len(boundary)) ) # iso_contours = pe.fill_closed_region_with_iso_contours(boundary, offset) # # init contour graph for iso contour by a distance relationaship matrix # iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) # graph.to_Mathematica("") # if not graph.is_connected(): # print("not connected") # ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset * 1.2)) # if(ret): # print("re-connect...") # graph.to_Mathematica("") # # generate a minimum-weight spanning tree # graph.to_reverse_delete_MST() # graph.to_Mathematica("") # # generate a minimum-weight spanning tree # pocket_graph = graph.gen_pockets_graph() # pocket_graph.to_Mathematica("") # # generate spiral for each pockets # # deep first search # spirals = {} # pe.dfs_connect_path_from_bottom(0, pocket_graph.nodes, iso_contours_2D, spirals, offset) # spirals[0] = pe.smooth_curve_by_savgol(spirals[0], 3, 1) # pathengine.suPath2D.draw_line(spirals[0], pe.im, [100,255,100],line_width) # id_sp = 0 # kappa, smooth = css.compute_curve_css(spirals[id_sp], 4) # css_idx = css.find_css_point(kappa) # for i in css_idx: # cv2.circle(pe.im, tuple(spirals[id_sp][i].astype(int)), 2, (255,255,0), -1) # iB += 1 ##test # for l in iso_contours_2D: # pathengine.suPath2D.draw_line(l, pe.im, [0,0,255],line_width) ##test name_head = "../cpp_" origin_im_name = name_head + str(abs(offset) * 3) + "cm.png" smooth_im_name = name_head + "smooth_" + str(abs(offset) * 3) + "cm.png" origin_cov_im_name = name_head + "cov_" + str(abs(offset) * 3) + "cm.png" smooth_cov_im_name = name_head + "cov_smooth_" + str(abs(offset) * 3) + "cm.png" cv2.imwrite(origin_im_name, pe.im) cv2.imwrite(smooth_im_name, sm_im) cv2.imwrite(origin_cov_im_name, pe_cov_im) cv2.imwrite(smooth_cov_im_name, sm_cov_im) resizeImg = cv2.resize(pe.im, (1000,1000)) cv2.imshow("Origin", resizeImg) resizeImg = cv2.resize(sm_im, (1000,1000)) cv2.imshow("Smooth", resizeImg) cv2.waitKey(0)
def fill(self): try: i = self.sl.value() self.message("Show slice {}.".format(i + 1), False) curdir = os.getcwd() filepath = self.out_path % i offset = -6 line_width = 1 #int(abs(offset)/2) pe = pathengine.pathEngine() pe.generate_contours_from_img(filepath, True) pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_contour = pe.get_contours_from_each_connected_region( contour_tree, '0') #draw boundaries ################################# # Generate N color list ################################# def generate_RGB_list(N): import colorsys HSV_tuples = [(x * 1.0 / N, 0.8, 0.9) for x in range(N)] RGB_tuples = map(lambda x: colorsys.hsv_to_rgb(*x), HSV_tuples) rgb_list = tuple(RGB_tuples) return np.array(rgb_list) * 255 N = 50 colors = generate_RGB_list(N) for boundary in group_contour.values(): iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) idx = 0 for cs in iso_contours: for c in cs: pathengine.suPath2D.draw_line(np.vstack([c, c[0]]), pe.im, colors[idx], line_width) idx += 1 cv2.imwrite(filepath, pe.im) tex1 = cv2.cvtColor(pe.im, cv2.COLOR_BGR2RGBA) v1 = gl.GLImageItem(tex1) v1.translate(0, 0, i * self.mesh_info.layer_thickness) self.view_slice.items = [] self.view_slice.addItem(v1) except Exception as e: self.message(str(e)) # gen fermat's curve # gen 3d point n*3 matrix #n = 51 #y = np.linspace(-10,10,n) #x = np.linspace(-10,10,100) #for i in range(n): #yi = np.array([y[i]]*100) #d = (x**2 + yi**2)**0.5 #z = 10 * np.cos(d) / (d+1) #pts = np.vstack([x,yi,z]).transpose() #plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,n*1.3)), width=(i+1)/10., antialias=True) #self.view_slice.addItem(plt) return
def test_fill_from_CSS(filepath, offset, is_reverse_img=True): pe = pathengine.pathEngine() def dfs_connect_path_from_bottom(i, nodes, iso_contours_2D, spirals, offset): node = nodes[i] msg = '{} make spiral {}'.format(i + 1, np.asarray(node.data) + 1) print(msg) cs = [] for ii in node.data: cs.append(iso_contours_2D[ii]) spirals[i] = pe.build_spiral_for_pocket(cs, True) if (len(node.next) > 0): for ic in node.next: dfs_connect_path_from_bottom(ic, nodes, iso_contours_2D, spirals, offset) return #1.find contours from slice pe.generate_contours_from_img(filepath, is_reverse_img) contour_tree = pe.convert_hiearchy_to_PyPolyTree() group_boundary = pe.get_contours_from_each_connected_region( contour_tree, '0') pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR) #2.filling each connected region dist_th = abs( offset) * 1.1 # contour distance threshold between adjacent layers iB = 0 for boundary in group_boundary.values(): print("Region {}: has {} boundry contours.".format(iB, len(boundary))) iso_contours = pe.fill_closed_region_with_iso_contours( boundary, offset) # init contour graph for iso contour by a distance relationaship matrix iso_contours_2D, graph = pe.init_isocontour_graph(iso_contours) graph.to_Mathematica("") if not graph.is_connected(): print("not connected") ret = pe.reconnect_from_leaf_node(graph, iso_contours, abs(offset * 1.2)) if (ret): print("re-connect...") graph.to_Mathematica("") # generate a minimum-weight spanning tree graph.to_reverse_delete_MST() graph.to_Mathematica("") # generate a minimum-weight spanning tree pocket_graph = graph.gen_pockets_graph() pocket_graph.to_Mathematica("") # generate spiral for each pockets # deep first search spirals = {} dfs_connect_path_from_bottom(0, pocket_graph.nodes, iso_contours_2D, spirals, offset) i = 0 for s in spirals.values(): pathengine.suPath2D.draw_line(s, pe.im, colors[i], 1) i = i + 1 #debug: draw all spiral if len(spirals) < 2: continue id1 = 9 kappa, smooth = css.compute_curve_css(spirals[id1], 4) css_idx = css.find_css_point(kappa) for i in css_idx: cv2.circle(pe.im, tuple(spirals[id1][i].astype(int)), 2, colors[id1], -1) id2 = 8 kappa, smooth = css.compute_curve_css(spirals[id2], 4) css_idx = css.find_css_point(kappa) for i in css_idx: cv2.circle(pe.im, tuple(spirals[id2][i].astype(int)), 2, colors[id2], -1) id2 = 5 kappa, smooth = css.compute_curve_css(spirals[id2], 4) css_idx = css.find_css_point(kappa) for i in css_idx: cv2.circle(pe.im, tuple(spirals[id2][i].astype(int)), 2, colors[id2], -1) #debug: connect two pockets #s = test_connect_two_pockets(pe, spirals[id1], spirals[id2], offset) pathengine.suPath2D.draw_line(s, pe.im, colors[5], 1) iB += 1 cv2.imshow("Art", pe.im) cv2.imwrite("r:/222.png", pe.im) cv2.waitKey(0)