def preprocess_cfr(ceilings_org, walls_org, obj): ''' Z is up, Y is thickness A ceiling is good: (1) not contains multiple rooms: cover no other ceilings (2) >= 3 edge walls A edge wall of a ceiling: In three points of the wall cenline: two corners and centroid at least two are on an edge of ceiling ''' assert ceilings_org.ndim == walls_org.ndim == 2 dis_threshold = 0.07 if ceilings_org.shape[0] == 0: return ceilings_org if walls_org.shape[0] == 0: return np.zeros(shape=[0, 7], dtype=np.float32) #Bbox3D.draw_bboxes(walls_org, 'Z', False) #Bbox3D.draw_bboxes(ceilings_org, 'Z', False) ceilings = ceilings_org.copy() ceilings, keep_ids0 = clean_repeat(ceilings) walls = walls_org.copy() cn = ceilings.shape[0] ceilings[:, 2] = 0 walls[:, 2] = 0 walls[:, 5] = 0 ceil_corners0 = Bbox3D.bboxes_corners(ceilings, 'Z') ceil_corners = np.take(ceil_corners0, Bbox3D._zpos_vs, axis=1) ceil_corners[:, :, 2] = 0 ceiling_cens = ceilings[:, 0:3] wall_cenlines = Bbox3D.bboxes_centroid_lines(walls, 'X', 'Z') good_ceiling_ids0 = [] bad_small_ids = [] for c in range(cn): # (1) #print(f'c:{c}') ceil_c = ceilings[c:c + 1].copy() ceil_c[:, 3:6] += 0.2 mask_overlap = Bbox3D.points_in_bbox(ceil_corners.reshape([-1, 3]), ceil_c).reshape([cn, 4]) mask_overlap = mask_overlap.all(1) num_overlap = mask_overlap.sum() - 1 ol_ids = np.where(mask_overlap)[0] ol_ids = [i for i in ol_ids if i != c] #if any_overlap: # area_ol = np.product(tmp[ol_ids,3:5], axis=1).sum() # area_c = np.product(ceilings[c,3:5]) # area_ol_rate = area_ol / area_c # import pdb; pdb.set_trace() # XXX BREAKPOINT # pass if Debug and 0: print(f'ceiling, contain {num_overlap} other celings') box_show = np.concatenate([walls_org, ceilings_org[c:c + 1]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) if num_overlap > 1: continue #if num_overlap >0: # bad_small_ids += ol_ids # (2) edge_wall_num, winc_state = is_edge_wall_of_ceiling( wall_cenlines, ceilings[c], walls_org) if edge_wall_num >= 3 or (edge_wall_num == 2 and (winc_state == 3).all()): good_ceiling_ids0.append(c) #good_ceiling_ids1 = [i for i in good_ceiling_ids0 if i not in bad_small_ids] good_ceiling_ids1 = keep_ids0[good_ceiling_ids0] good_ceiling_ids1 = np.array(good_ceiling_ids1).astype(np.int) rm_num = cn - good_ceiling_ids1.shape[0] bad_ceiling_ids = np.array( [i for i in range(cn) if i not in good_ceiling_ids1]).astype(np.int32) new_ceilings = ceilings_org[good_ceiling_ids1] if Debug and rm_num > 0: print(f'{cn} -> {good_ceiling_ids1.shape[0]}') box_show = np.concatenate([walls_org, ceilings_org[good_ceiling_ids1]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) if rm_num > 0: box_show = np.concatenate( [walls_org, ceilings_org[bad_ceiling_ids]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT #show_walls_1by1(new_ceilings) pass return new_ceilings
def preprocess_doors(doors0, walls, door_thickness=0.18): ''' doors0:[d,7] walls:[w,7] ''' door_n = doors0.shape[0] if door_n == 0: return doors0 wall_n = walls.shape[0] walls_1 = walls.copy() # (1) Find the coresponding wall of each door # (1.1) Get the four top lines of each door door_corners = Bbox3D.bboxes_corners(doors0, 'Z')[:, 0:4, :] # [d,4,3] door_lines0 = np.take(door_corners, Bbox3D._lines_z0_vids, axis=1) # [d,4,2,3] door_lines1 = door_lines0.reshape(-1, 2, 3) # (1.2) Get the centroid lines of each wall wall_cen_lines = Bbox3D.bboxes_centroid_lines(walls_1, 'X', 'Z') # (1.3) Get the intersections_2d between lines and walls # A door matches a wall means: there are two top lines of the door, which are # intersected with the wall centroid line. dw_ints = lines_intersection_2d(door_lines1[:, :, 0:2], wall_cen_lines[:, :, 0:2], True, True) dw_ints = dw_ints.reshape(door_n, 4, wall_n, 2) # [d,4,w,2] tmp0 = (1 - np.isnan(dw_ints)).sum(3) # [d,4,w] door_mask0 = tmp0.sum(1) == 4 door_matched0 = door_mask0.sum(1).reshape(-1, 1) # (1.4) Sometimes on door can match two walls. Remove the confused one by: # The right wall should not contain any corners dc_in_wall_mask = Bbox3D.points_in_bbox(door_corners.reshape(-1, 3), walls).reshape(door_n, 4, wall_n) dc_in_wall_mask = np.any(dc_in_wall_mask, axis=1) bad_match = (door_matched0 > 1) * dc_in_wall_mask door_mask = door_mask0 * (1 - bad_match) door_ids, wall_ids = np.where(door_mask) success_num = door_ids.shape[0] # (2) Pick the failed door ids wall_num_each_door = door_mask.sum(1) fail_match_door_ids = np.where(wall_num_each_door != 1)[0] walls_good = walls[wall_ids] yaws = limit_period(walls_good[:, -1], 0, np.pi / 2) intersections_2d = [] for i in range(success_num): door_idx = door_ids[i] cids = np.where(tmp0[door_idx, :, wall_ids[i]])[0] ints_i = dw_ints[door_idx, cids, wall_ids[i]] intersections_2d.append(ints_i.reshape(1, 2, 2)) if len(intersections_2d) == 0: return np.empty([0, 7]) intersections_2d = np.concatenate(intersections_2d, 0) doors_centroids_2d = np.mean(intersections_2d, 1) doors_length = np.linalg.norm(intersections_2d[:, 0] - intersections_2d[:, 1], axis=1) doors_length -= door_thickness * np.sin(yaws * 2) doors_new = doors0[door_ids].copy() doors_new[:, 0:2] = doors_centroids_2d doors_new[:, 3] = doors_length doors_new[:, 4] = door_thickness doors_new[:, 6] = walls_good[:, -1] if DEBUG and fail_match_door_ids.shape[0] > 0: print(f"fail_match_door_ids:{fail_match_door_ids}") show_all([doors0[fail_match_door_ids], walls]) #for dids in fail_d_ids: # fail_w_ids = np.where(door_mask[dids])[0] # show_all([doors0[dids].reshape(-1,7), walls[fail_w_ids].reshape(-1,7)]) import pdb pdb.set_trace() # XXX BREAKPOINT pass if DEBUG: show_all([doors0, doors_new, walls]) return doors_new
def merge_2pieces_of_1wall(bbox0, bbox1, dim): ''' [1,7] [1,7] two box can merge, when: z, size_y, size_z same yaw0 = yaw1 = angle of c0_c1 out: [1,7] ''' from utils3d.geometric_util import angle_with_x assert dim == 'X' or 'Y' dim = 0 if dim == 'X' else 1 bbox0 = bbox0.reshape([1, 7]) bbox1 = bbox1.reshape([1, 7]) dif = bbox1 - bbox0 dif[0, -1] = limit_period(dif[0, -1], 0.5, np.pi) z_same = np.abs(dif[0, 2]) < 0.01 if dim == 0: # o means the other here, if dim=='X', o='Y' so_same = np.abs(dif[0, 3 + 1 - dim]) < 0.05 else: so_same = np.abs(dif[0, 3 + 1 - dim]) < 0.15 sz_same = np.abs(dif[0, 3 + 2]) < 0.01 z_sames0 = z_same and sz_same if z_sames0: z_sames = z_sames0 else: z0_max = bbox0[0, 2] + bbox0[0, 5] * 0.5 z0_min = bbox0[0, 2] - bbox0[0, 5] * 0.5 z1_max = bbox1[0, 2] + bbox1[0, 5] * 0.5 z1_min = bbox1[0, 2] - bbox1[0, 5] * 0.5 zmin_dif = np.abs(z1_min - z0_min) zmax_dif = np.abs(z1_max - z0_max) zmin_same = zmin_dif < 0.01 zmax_same = zmax_dif < 0.03 z_sames = zmin_same and zmax_same if not zmax_same: iou_xy = rotate_iou_gpu(bbox0[:, [0, 1, 3, 4, 6]], bbox1[:, [0, 1, 3, 4, 6]]) #print(f'box0 : {bbox0}') #print(f'box1 : {bbox1}') print( f'zmin_dif:{zmin_dif}, zmax_dif:{zmax_dif}\n iou_xy:{iou_xy}\n' ) if iou_xy > MERGE_Z_ANYWAY_XYIOU_THRESHOLD: print('Merge even z is different') z_sames = True else: print('abort merging because of z is different') if DEBUG and False: box_show = np.concatenate([bbox0, bbox1], 0) Bbox3D.draw_bboxes(box_show, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT pass if z_sames: zmin_new = min(z0_min, z1_min) zmax_new = max(z0_max, z1_max) z_new = (zmin_new + zmax_new) / 2.0 z_size_new = zmax_new - zmin_new bbox0[0, 2] = z_new bbox0[0, 5] = z_size_new bbox1[0, 2] = z_new bbox1[0, 5] = z_size_new yaw_same = np.abs(dif[0, -1]) < 0.05 if not (z_sames and so_same and yaw_same): return None cen_direc = dif[:, 0:2] if dim == 0: cen_line0 = Bbox3D.bboxes_centroid_lines(bbox0, 'X', 'Z') dis_01 = vertical_dis_1point_lines(bbox1[0, 0:3], cen_line0)[0] overlap_mask0 = dis_01 < bbox0[0, 4] * 0.51 + 0.01 if not overlap_mask0: return None cen_dis = np.linalg.norm(dif[0, 0:3]) overlap_mask1 = cen_dis < (bbox0[0, 3] + bbox1[0, 3]) * 0.5 + 0.01 if not overlap_mask1: return None centroid_lines1 = Bbox3D.bboxes_centroid_lines(bbox1, 'X' if dim == 1 else 'Y', 'Z') cen_dis = vertical_dis_1point_lines(bbox0[0, 0:3], centroid_lines1)[0] size_dim0 = bbox0[0, 3 + dim] size_dim1 = bbox1[0, 3 + dim] is_box0_covered_by_1 = size_dim1 * 0.5 > cen_dis + size_dim0 * 0.5 is_box1_covered_by_0 = size_dim0 * 0.5 > cen_dis + size_dim1 * 0.5 if is_box0_covered_by_1: merged = bbox1 elif is_box1_covered_by_0: merged = bbox0 else: k = size_dim1 / (size_dim0 + size_dim1) new_centroid = bbox0[0, 0:3] + (bbox1[0, 0:3] - bbox0[0, 0:3]) * k new_size_dim = (size_dim0 + size_dim1) / 2 + cen_dis merged = (bbox0 + bbox1) / 2 merged[:, -1] = ave_angles(bbox0[:, -1], bbox1[:, -1], scope_id=1) if np.abs(bbox1[0, -1] - bbox0[0, -1]) > np.pi * 0.5: merged[0, -1] = (np.abs(bbox0[0, -1]) + np.abs(bbox1[0, -1])) / 2.0 merged[0, 0:3] = new_centroid merged[0, 3 + dim] = new_size_dim # show = False if show: box_show = np.concatenate([bbox0, bbox1, merged], 0) box_show[2, 2] += 0.1 Bbox3D.draw_bboxes(box_show, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT pass return merged
def find_close_walls(walls): ''' walls: [n,7] ''' show = False if show: walls0 = walls.copy() corners = Bbox3D.bboxes_corners(walls, 'Z') # [n,8,3] cen_lines_x = Bbox3D.bboxes_centroid_lines(walls, 'X', 'Z') # [n,2,3] cen_lines_y = Bbox3D.bboxes_centroid_lines(walls, 'Y', 'Z') # [n,2,3] n = walls.shape[0] dis_x0 = vertical_dis_points_lines( corners.reshape([-1, 3])[:, 0:2], cen_lines_x[:, :, 0:2]).reshape([n, 8, n]) dis_x_ave = dis_x0.mean(1) # [n,n] dis_x_max = dis_x0.max(1) # [n,n] inside_x_ave = dis_x_ave / (walls[:, 4].reshape([1, n]) * 0.501 + 0.01) inside_x_max = dis_x_max / (walls[:, 4].reshape([1, n]) * 0.8 + 0.03) inside_x_mask = (inside_x_ave < 1) * (inside_x_max < 1) dis_y0 = vertical_dis_points_lines( corners.reshape([-1, 3])[:, 0:2], cen_lines_y[:, :, 0:2]).reshape([n, 8, n]) dis_y_ave = dis_y0.max(1) # [n,n] dis_y_max = dis_y0.max(1) # [n,n] inside_y_ave = dis_y_ave / (walls[:, 3].reshape([1, n]) * 0.515 + 0.03) inside_y_max = dis_y_max / (walls[:, 3].reshape([1, n]) * 0.55 + 0.05) inside_y_mask = (inside_y_ave < 1) * (inside_y_max < 1) inside_mask = inside_x_mask * inside_y_mask # inside_mask[i,j] is True means walls[i] is inside of walls[j] #print(inside_x) #print(inside_y) #print(inside_mask) remain_mask = np.array([True] * n) for i in range(n - 1): for j in range(i + 1, n): if inside_mask[i, j] or inside_mask[j, i]: if inside_mask[i, j] and inside_mask[j, i]: # (A) If inside with each other, merge two close walls walls[j] = merge_2close_walls(walls[i], walls[j]) remain_mask[i] = False elif inside_mask[i, j]: # (B) If one is inside another, remove the inside one remain_mask[i] = False elif inside_mask[j, i]: remain_mask[j] = False walls_new = walls[remain_mask] rm_n = np.sum(remain_mask) print(f'clean close walls {n} -> {rm_n}') if show: show_boxes = walls0 show_boxes[:, 2] -= 0.2 show_boxes = np.concatenate([show_boxes, walls_new], 0) Bbox3D.draw_bboxes(show_boxes, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT #show_walls_offsetz(walls_new) #show_walls_1by1(walls_new) return walls_new
def merge_pieces_of_same_walls_alongY(wall_bboxes): ''' 1) Find all the walls which are A) parallel along X, B) one of cen_corners is very close C) centroid of one wall is inside of another 2) Merge along Y ''' from utils3d.geometric_util import angle_with_x, vertical_dis_points_lines if wall_bboxes.shape[0] == 0: return wall_bboxes show = False if show: wall_bboxes0 = wall_bboxes.copy() wall_bboxes0[:, 2] -= 1 n = wall_bboxes.shape[0] cen_lines = Bbox3D.bboxes_centroid_lines(wall_bboxes, cen_axis='X', up_axis='Z') # [n,2,3] cen_direc = cen_lines[:, 1, :] - cen_lines[:, 0, :] # [n,3] np.linalg.norm(cen_direc[:, 0:2], axis=1) angles = angle_with_x(cen_direc[:, 0:2], 1) boxes_merged_extra = [] remain_mask = np.array([True] * n) merge_y_num = 0 split_and_merge_num = 0 for i in range(n - 1): # 1) parallel along X angles_dif = angles[i] - angles[i + 1:] # make to [0,np.pi/2] angles_dif = np.abs(limit_period(angles_dif, 0.5, np.pi)) angle_mask = angles_dif < 7 * np.pi / 180 # 2) one of centroid line corners is very close cen_dis = cen_lines[i:i + 1].reshape( [1, 2, 1, 3]) - cen_lines[i + 1:].reshape([-1, 1, 2, 3]) cen_dis = np.linalg.norm(cen_dis, axis=3) cen_dis_min = cen_dis.min(axis=1).min(axis=1) cen_dis_max = cen_dis.max(axis=1).max(axis=1) thickness_sum = wall_bboxes[:, 4] * 0.5 + wall_bboxes[i, 4] * 0.5 thickness_sum = thickness_sum[i + 1:] cendis_mask = cen_dis_min < thickness_sum # 3) the other centroid line corner is inside of the long box centroid_dis = np.linalg.norm(wall_bboxes[i:i + 1, 0:3] - wall_bboxes[i + 1:, 0:3], axis=1) #tmp = np.maximum(wall_bboxes[i,3], wall_bboxes[i+1:,3]) tmp = (wall_bboxes[i, 3] + wall_bboxes[i + 1:, 3]) * 0.45 - 0.1 centroid_mask = centroid_dis < tmp #if i==4: # import pdb; pdb.set_trace() # XXX BREAKPOINT # show_boxes = wall_bboxes[[4,12]] # Bbox3D.draw_bboxes(show_boxes, 'Z', False) # pass mask_i = angle_mask * cendis_mask * centroid_mask if mask_i.any(): ids = np.where(mask_i)[0] + i + 1 # 5) the centroid corner used to split the other # 4) vertical dis vertical_dis = vertical_dis_points_lines(cen_lines[i], cen_lines[ids]).mean(0) ave_thickness = (wall_bboxes[i, 4] + wall_bboxes[ids, 4]) * 0.5 thickness_gap_rate = vertical_dis / ave_thickness verdis_mask = (thickness_gap_rate > 0.2) * (thickness_gap_rate < 1.2) ids = ids[verdis_mask] vertical_dis = vertical_dis[verdis_mask] is_need_merge = ids.shape[0] > 0 if is_need_merge: # split the longer box, and merge the shorter one along Y k = ids.shape[0] for j in range(k): idx = ids[j] size_x_i = wall_bboxes[i, 3] size_x_j = wall_bboxes[idx, 3] size_x_rate = size_x_i / size_x_j print(f'size_x_rate: {size_x_rate}') if np.abs(size_x_rate - 1) < 0.15: merge_y_num += 1 box_merge = merge_2pieces_of_1wall( wall_bboxes[i], wall_bboxes[idx], 'Y') if show and False: show_boxes = np.concatenate([ wall_bboxes[i:i + 1], wall_bboxes[idx:idx + 1] ], 0) if box_merge is not None: show_boxes = np.concatenate( [show_boxes, box_merge], 0) show_boxes[-1, 2] += 0.2 else: import pdb pdb.set_trace() # XXX BREAKPOINT pass show_boxes = np.concatenate( [show_boxes, wall_bboxes0], 0) Bbox3D.draw_bboxes(show_boxes, 'Z', False) pass if box_merge is not None: wall_bboxes[idx] = box_merge.reshape([7]) remain_mask[i] = False else: print( 'The two walls cannot be merged along Y, this should not happen normally' ) print( 'merge_pieces_of_same_walls_alongY again after crop_walls to solve some special case: Originally, a wall is broken by no intersection like 0058113bdc8bee5f387bb5ad316d7b28' ) #show_boxes = np.concatenate([wall_bboxes[i:i+1], wall_bboxes[idx:idx+1]], 0) #Bbox3D.draw_bboxes(wall_bboxes, 'Z', False, highlight_ids=[idx, i]) #Bbox3D.draw_bboxes(show_boxes, 'Z', False) #import pdb; pdb.set_trace() # XXX BREAKPOINT #pass #raise NotImplementedError else: # the longer box need to be split along X before merging split_and_merge_num += 1 cen_dis_ij = cen_dis[idx - i - 1] if size_x_rate > 1: longer_idx = i short_idx = idx cen_dis_ij = cen_dis_ij.min(axis=0) else: longer_idx = idx short_idx = i cen_dis_ij = cen_dis_ij.min(axis=1) # find the intersection point on longer box far_corner_id = int(cen_dis_ij[0] < cen_dis_ij[1]) cen_dir_longer = cen_lines[longer_idx, 1] - cen_lines[longer_idx, 0] cen_dir_longer /= np.linalg.norm(cen_dir_longer) sl_dir = cen_lines[ short_idx, far_corner_id] - cen_lines[longer_idx, 0] intersection = np.sum( sl_dir * cen_dir_longer ) * cen_dir_longer + cen_lines[longer_idx, 0] # offset: half of the thickness intersection += cen_dir_longer * wall_bboxes[i, 4] * 0.5 splited_boxes = Bbox3D.split_wall_by_centroid_intersections( wall_bboxes[longer_idx], intersection.reshape([1, 3])) # [2,7] if splited_boxes.shape[0] == 1: print( '\n\n\t\tComplicated situation, not solved well yet.\n\n' ) box_merge = None if False and DEBUG and splited_boxes.shape[0] == 1: box_tmp = np.array( [[0, 0, 0, 0.5, 0.5, 0.5, 0]]) box_tmp[0, 0:3] = intersection.reshape([1, 3]) boxes_show = np.concatenate([ box_tmp, wall_bboxes[longer_idx].reshape( [-1, 7]) ], 0) Bbox3D.draw_points_bboxes( intersection.reshape([1, 3]), boxes_show, 'Z', False) else: tmp = wall_bboxes[short_idx, 0:3] - splited_boxes[:, 0: 3] # [2,3] tmp = np.linalg.norm(tmp, axis=1) # [2] merge_id = int(tmp[0] > tmp[1]) box_merge = merge_2pieces_of_1wall( wall_bboxes[short_idx], splited_boxes[merge_id], 'Y') if show and False: #if box_merge is None: show_boxes = np.concatenate([ wall_bboxes[i:i + 1], wall_bboxes[idx:idx + 1] ], 0) Bbox3D.draw_points_bboxes( intersection.reshape([1, 3]), show_boxes, 'Z', False) show_boxes = np.concatenate( [show_boxes, splited_boxes], 0) show_boxes[-1, 2] += 0.5 show_boxes[-2, 2] += 0.7 if box_merge is not None: show_boxes = np.concatenate( [show_boxes, box_merge], 0) show_boxes[-1, 2] += 1 show_boxes = np.concatenate( [show_boxes, wall_bboxes0], 0) Bbox3D.draw_bboxes(show_boxes, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT pass if box_merge is None: # temperally solution, may because of a wall being changed several # times remain_mask[short_idx] = False else: wall_bboxes[longer_idx] = splited_boxes[1 - merge_id] wall_bboxes[short_idx] = box_merge.reshape([7]) boxes_merged_extra.append(box_merge.reshape([1, 7])) wall_bboxes_new = wall_bboxes[remain_mask] #boxes_merged_extra = np.concatenate(boxes_merged_extra, 0) #wall_bboxes_new = np.concatenate([wall_bboxes, boxes_merged_extra], 0) print( f'merge_y_num:{merge_y_num} split_and_merge_num:{split_and_merge_num}' ) if show: show_walls_offsetz(wall_bboxes_new) #show_walls_offsetz(wall_bboxes) #show_walls_offsetz(wall_bboxes0[remain_mask]) show_walls_offsetz(wall_bboxes0[np.logical_not(remain_mask)]) #show_walls_offsetz(boxes_merged_extra) return wall_bboxes_new
def preprocess_cfr(ceilings_org, walls_org, obj): ''' Z is up, Y is thickness ''' #Bbox3D.draw_bboxes(walls, 'Z', False) ceilings = ceilings_org.copy() walls = walls_org.copy() walls = replace_slant_walls(walls) dis_threshold = 0.07 ceiling_cens = ceilings[:, 0:3] ceiling_cens[:, 2] = 0 ceil_cenlines_x = Bbox3D.bboxes_centroid_lines(ceilings, 'X', 'Z') ceil_cenlines_x[:, :, 2] = 0 #ceil_cenlines_y = Bbox3D.bboxes_centroid_lines(ceilings, 'Y', 'Z') wall_cenlines = Bbox3D.bboxes_centroid_lines(walls, 'X', 'Z') wall_cenlines[:, :, 2] = 0 ceilings_shrink = ceilings.copy() ceilings_shrink[:, 3:5] -= 0.3 cn = ceilings.shape[0] ## Find edge wall nums good_ceiling_ids = [] for c in range(cn): # (0.1) If no any other overlap ceiling, try to keep it # Otherwise, delete it when >3 wall inside ceiling tmp = np.delete(ceiling_cens.copy(), c, axis=0) any_overlap = Bbox3D.points_in_bbox(tmp, ceilings[c:c + 1]).any() if any_overlap: wall_corner0_in_ceil = Bbox3D.points_in_bbox( wall_cenlines[:, 0, :], ceilings_shrink[c:c + 1]) wall_corner1_in_ceil = Bbox3D.points_in_bbox( wall_cenlines[:, 1, :], ceilings_shrink[c:c + 1]) wall_inside_ceil = wall_corner0_in_ceil + wall_corner1_in_ceil wall_inside_ceil_ids = np.where(wall_inside_ceil)[0] nwic = wall_inside_ceil_ids.shape[0] if nwic > 3: if Debug and 1: print(f'bad ceiling, contain {nwic} walls inside') box_show = np.concatenate( [walls_org, ceilings_org[c:c + 1]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) box_show = np.concatenate([ walls_org[wall_inside_ceil_ids], ceilings_org[c:c + 1] ], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT continue # (1) the central corners of wall are inside of ceiling wall_cenlines_auged = line_aug(wall_cenlines) cw_cen_dis = ceiling_cens[c].reshape([1, 1, -1]) - wall_cenlines_auged cw_cen_dis = np.linalg.norm(cw_cen_dis, axis=2) ceil_diag_size = np.linalg.norm(ceilings[c, 3:5]) on_inside_ceil = (cw_cen_dis - ceil_diag_size / 2 < dis_threshold).sum(1) >= 2 if Debug and 0: #Bbox3D.draw_points_bboxes(wall_cenlines_auged.reshape([-1,3]), walls, 'Z', False) inside_ids = np.where(on_inside_ceil)[0] box_show = np.concatenate( [walls_org[inside_ids], ceilings_org[c:c + 1]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) # (2) along x: wall central line is on x boundaries of ceiling dis_cw = vertical_dis_points_lines(ceil_cenlines_x[c], wall_cenlines) ceil_y_thickness = ceilings[c, 4] mask_x0 = np.abs(dis_cw[0] - dis_cw[1]) < dis_threshold mask_x1 = (np.abs(dis_cw - ceil_y_thickness / 2) < dis_threshold).all(0) mask_x = mask_x0 * mask_x1 * on_inside_ceil wall_on_ceil_boundary_parall_x = np.where(mask_x)[0] num_edgew_x = clean_edge_wall_same_side( wall_cenlines[wall_on_ceil_boundary_parall_x]) # (3) along x: wall central line is on x boundaries of ceiling ceil_x_thickness = ceilings[c, 3] mask_y0 = dis_cw < dis_threshold mask_y1 = np.abs(dis_cw - ceil_x_thickness) < dis_threshold mask_y = (mask_y0 + mask_y1).all(0) mask_y = mask_y * on_inside_ceil wall_on_ceil_boundary_parall_y = np.where(mask_y)[0] num_edgew_y = clean_edge_wall_same_side( wall_cenlines[wall_on_ceil_boundary_parall_y]) #Bbox3D.point_in_box(wall_cenlines, ceilings[]) edge_wall_num = num_edgew_x + num_edgew_y if edge_wall_num >= 3: good_ceiling_ids.append(c) if Debug and edge_wall_num < 3 and 0: print(f'edge_wall_num: {edge_wall_num}') box_show = np.concatenate([walls_org, ceilings_org[c:c + 1]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) #Bbox3D.draw_points_bboxes(ceil_cenlines_x[c], box_show, 'Z', False) #Bbox3D.draw_points_bboxes(ceil_cenlines_x[c], ceilings[c:c+1], 'Z', False) edge_walls_x = walls_org[wall_on_ceil_boundary_parall_x] box_x = np.concatenate([edge_walls_x, ceilings_org[c:c + 1]], 0) #Bbox3D.draw_bboxes_mesh(box_x, 'Z', False) edge_walls_y = walls_org[wall_on_ceil_boundary_parall_y] box_y = np.concatenate([edge_walls_y, ceilings_org[c:c + 1]], 0) #Bbox3D.draw_bboxes_mesh(box_y, 'Z', False) walls_inside = walls_org[wall_inside_ceil_ids] box_ins = np.concatenate([walls_inside, ceilings_org[c:c + 1]], 0) #Bbox3D.draw_bboxes_mesh(box_ins, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT pass good_ceiling_ids = np.array(good_ceiling_ids).reshape([-1]) new_cn = good_ceiling_ids.shape[0] print(f'\n\n{obj} {cn} -> {new_cn}') if new_cn == 0: new_ceilings = ceilings_org[0:0] else: new_ceilings = ceilings_org[good_ceiling_ids] if Debug and new_cn < cn: print(good_ceiling_ids) box_show = np.concatenate([walls_org, new_ceilings], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) bad_ceil_ids = np.array([ i for i in range(cn) if i not in good_ceiling_ids ]).astype(np.int32) if bad_ceil_ids.shape[0] > 0: box_show = np.concatenate([walls_org, ceilings_org[bad_ceil_ids]], 0) Bbox3D.draw_bboxes_mesh(box_show, 'Z', False) import pdb pdb.set_trace() # XXX BREAKPOINT return ceilings