def create_env(self, config_path, house_id, render_width=args.render_width, render_height=args.render_height): api = objrender.RenderAPIThread(w=render_width, h=render_height, device=0) cfg = load_config(config_path) self.env = Environment(api, house_id, cfg)
def cache_path_images(hid_to_qns, args): # make last several key frames of navigation api_thread = objrender.RenderAPIThread(w=args.render_width, h=args.render_height) # make frames problematic_qids = [] for hid, qns in tqdm(hid_to_qns.items()): print('Processing:', hid) # initialize environment env = Environment(api_thread, hid, cfg, ColideRes=500) # rgb, semantic, cube_rgb (Licheng: assume pre-trained cnn is good at cnn -> depth) for qn in qns: # path json path_name = '.'.join([qn['house']] + [box['id'] for box in qn['bbox']])+'.json' path_file = osp.join(args.shortest_path_dir, path_name) paths = json.load(open(path_file)) # list of [{positions, actions, best_iou, ordered}] # path h5 output_h5 = osp.join(args.output_dir, '.'.join([qn['house']] + [box['id'] for box in qn['bbox']])+'.h5') # if osp.exists(output_h5): # continue # f = h5py.File(output_h5, 'w') f = h5py.File(output_h5, 'r+') if 'cube_rgb0' in list(f.keys()): # close if already written. print('cube_rgb already exists in %s' % output_h5) f.close() continue # render num_paths = min(args.num_paths, len(paths)) for pix in range(num_paths): path = paths[pix] # on default we use the first sampled path positions, actions, key_ixs, ordered = get_positions(path) # ego_rgb = np.zeros((len(positions), args.render_height, args.render_width, 3)) # (n, h, w, 3) # ego_depth = np.zeros((len(positions), args.render_height, args.render_width, 2)) # (n, h, w, 2) # ego_sem = np.zeros((len(positions), args.render_height, args.render_width, 3)) # (n, h, w, 3) cube_rgb = np.zeros((len(positions), 4, args.render_height, args.render_width, 3)) # (n, 4, h, w, 3) # cube_depth = np.zeros((len(positions), 4, args.render_height, args.render_width, 2)) # (n, 4, h, w, 2) for i, pos in enumerate(positions): # ego_rgb[i] = render(env, pos, mode='rgb') # ego_depth[i] = render(env, pos, mode='depth') # ego_sem[i] = render(env, pos, mode='semantic') cube_rgb[i] = render_cube_map(env, pos, mode='rgb') # cube_depth[i] = render_cube_map(env, pos, mode='depth') # save # f.create_dataset('ego_rgb%s'%pix, dtype=np.uint8, data=ego_rgb) # f.create_dataset('ego_depth%s'%pix, dtype=np.uint8, data=ego_depth) # f.create_dataset('ego_sem%s'%pix, dtype=np.uint8, data=ego_sem) f.create_dataset('cube_rgb%s'%pix, dtype=np.uint8, data=cube_rgb) # f.create_dataset('cube_depth%s'%pix, dtype=np.uint8, data=cube_depth) # f.create_dataset('key_ixs%s'%pix, dtype=np.uint8, data=np.array(key_ixs)) # f.create_dataset('ordered%s'%pix, dtype=np.uint8, data=np.array([ordered])) # f.create_dataset('positions%s'%pix, dtype=np.float32, data=np.array(positions)) # f.create_dataset('actions%s'%pix, dtype=np.uint8, data=np.array(actions)) # f.create_dataset('num_paths', dtype=np.uint8, data=np.array([num_paths])) f.close() print('%s cached.' % output_h5)
def _load_envs(self, start_idx=-1, in_order=False): if start_idx == -1: # next env start_idx = self.env_set.index(self.pruned_env_set[-1]) + 1 # pick envs self.pruned_env_set = self._pick_envs_to_load(self.split, self.max_threads_per_gpu, start_idx, in_order) if len(self.pruned_env_set) == 0: return # Load api threads start = time.time() if len(self.api_threads) == 0: for i in range(self.max_threads_per_gpu): self.api_threads.append( objrender.RenderAPIThread(w=self.width, h=self.height, device=self.gpu_id)) print('[%.2f] Loaded %d api threads' % (time.time() - start, len(self.api_threads))) # Load houses start = time.time() from multiprocessing import Pool _args = ([h, self.cfg, self.map_resolution] for h in self.pruned_env_set) with Pool(len(self.pruned_env_set)) as pool: self.all_houses = pool.starmap(local_create_house, _args) print('[%.02f] Loaded %d houses' % (time.time() - start, len(self.all_houses))) # Load envs start = time.time() self.env_loaded = {} for i in range(len(self.all_houses)): print('[%02d/%d][split:%s][gpu:%d][house:%s]' % (i + 1, len(self.all_houses), self.split, self.gpu_id, self.all_houses[i].house['id'])) env = Environment(self.api_threads[i], self.all_houses[i], self.cfg) self.env_loaded[self.all_houses[i].house['id']] = \ House3DUtils(env, target_obj_conn_map_dir=self.target_obj_conn_map_dir) print('[%.02f] Loaded %d house3d envs' % (time.time() - start, len(self.env_loaded))) for i in range(len(self.all_houses)): self.visited_envs.add(self.all_houses[i].house['id']) # Mark available data indices self.available_idx = [ i for i, v in enumerate(self.env_list) if v in self.env_loaded ] print('Available inds: %d' % len(self.available_idx))
def worker(): api_thread = objrender.RenderAPIThread(w=224, h=224) while True: i, house_id, qns = q.get() print('Processing house[%s] %s/%s' % (house_id, i + 1, len(house_to_qns))) # api_thread = objrender.RenderAPIThread(w=224, h=224) env = Environment(api_thread, house_id, cfg, ColideRes=args.colide_resolution) build_graph = True if osp.exists( osp.join(args.graph_dir, env.house.house['id'] + '.pkl')): build_graph = False h3d = House3DUtils( env, build_graph=build_graph, graph_dir=args.graph_dir, target_obj_conn_map_dir=args.target_obj_conn_map_dir) # make connMap for each qn for qn in qns: try: if 'object' in qn['type']: # object_color_compare_xroom(inroom), object_size_compare_xroom(inroom), object_dist_compare_inroom for bbox in qn['bbox']: assert bbox['type'] == 'object' obj = h3d.objects[bbox['id']] h3d.set_target_object( obj) # connMap computed and saved # we also store its room connMap room = h3d.rooms[bbox['room_id']] h3d.set_target_room( room) # connMap computed and saved elif qn['type'] in ['room_size_compare']: for bbox in qn['bbox']: assert 'room' in qn['type'] room = h3d.rooms[bbox['id']] h3d.set_target_room( room) # connMap computed and saved except: print('Error found for qn[%s]' % qn['id']) invalid.append(qn['id']) q.task_done()
def house_renderer(cfg, house_queue, progress_queue): while True: houseID, house = house_queue.get() api = objrender.RenderAPIThread(w=args.width, h=args.height, device=0) env = Environment(api, house, cfg) cam = api.getCamera() loc_idx = 0 valid_rooms = get_valid_rooms(house) for room in valid_rooms: for i in range(SAMPLES_PER_ROOM): reset_random(env, house, room) render_current_location(env, houseID, room['id'], loc_idx) loc_idx += 1 house_queue.task_done() progress_queue.put(1) print('Rendered house {}'.format(houseID))
def worker(): api_thread = objrender.RenderAPIThread(w=224, h=224) while True: i, house_id, qns = q.get() print('Processing house[%s] %s/%s' % (house_id, i + 1, len(house_to_qns))) # api_thread = objrender.RenderAPIThread(w=224, h=224) env = Environment(api_thread, house_id, cfg, ColideRes=args.colide_resolution) build_graph = True if osp.exists( osp.join(args.graph_dir, env.house.house['id'] + '.pkl')): build_graph = False h3d = House3DUtils( env, build_graph=build_graph, graph_dir=args.graph_dir, target_obj_conn_map_dir=args.target_obj_conn_map_dir) # objects in the house of interest object_ids = [] for qn in qns: if 'object' in qn['type']: for bbox in qn['bbox']: assert bbox['type'] == 'object' object_ids.append(bbox['id']) object_ids = list(set(object_ids)) # sample good-view points for each object for obj_id in tqdm(object_ids): save_file = osp.join(args.output_dir, house_id + '_' + obj_id + '.json') if osp.exists(save_file): continue # run and save points, ious = get_best_view_points(h3d, obj_id, args) json.dump({ 'points': points, 'ious': ious }, open(save_file, 'w')) q.task_done()
def house_renderer(cfg, house_queue, progress_queue): while True: houseID, house = house_queue.get() api = objrender.RenderAPIThread(w=512, h=512, device=0) env = Environment(api, house, cfg) loc_idx = 0 valid_rooms = get_valid_rooms(house) for room, room_type in valid_rooms: for _i in range(SAMPLES_PER_ROOM): if not reset_random(env, house, room): print('Unable to sample location for house {}'.format( houseID)) break render_current_location(env, houseID, room['id'], loc_idx, room_type) loc_idx += 1 house_queue.task_done() progress_queue.put(1) print('Rendered house {}'.format(houseID))
def main(): parser = argparse.ArgumentParser() parser.add_argument( '-questions_json', default='/private/home/akadian/eqa-data/suncg-data/eqa_v1.json') parser.add_argument( '-graph_dir', default='/private/home/akadian/eqa-data/suncg-data/a-star') parser.add_argument( '-target_obj_conn_map_dir', default= '/private/home/akadian/eqa-data/suncg-data/a-star/target_obj_conn_map_dir' ) parser.add_argument('-shortest_path_dir') parser.add_argument( '-invalids_dir', default='/private/home/akadian/eqa-data/suncg-data/invalids/') parser.add_argument('-env_id', default=None) parser.add_argument('-debug', action='store_true') parser.add_argument('-map_resolution', default=1000, type=int) parser.add_argument('-seed', type=int, required=True) parser.add_argument('-check_validity', action="store_true") parser.add_argument('-log_path', default=None) parser.add_argument('-source_candidate_fraction', type=float, default=0.05) args = parser.parse_args() if args.log_path is None: args.log_path = 'seed_{}_resolution_{}.{}.log'.format( args.seed, args.map_resolution, str(datetime.now()).replace(' ', '_')) logging.basicConfig(filename=args.log_path, level=logging.INFO, format='%(asctime)-15s %(message)s') random.seed(args.seed) np.random.seed(args.seed) if not os.path.exists(args.shortest_path_dir): os.makedirs(args.shortest_path_dir) args.gpus = os.environ['CUDA_VISIBLE_DEVICES'].split(',') args.gpus = [int(x) for x in args.gpus] # create specific directories corresponding to the resolution args.graph_dir = os.path.join(args.graph_dir, str(args.map_resolution)) args.target_obj_conn_map_dir = os.path.join(args.target_obj_conn_map_dir, str(args.map_resolution)) # load house3d renderer cfg = load_config('../../House3D/tests/config.json') api_thread = objrender.RenderAPIThread(w=224, h=224, device=args.gpus[0]) # load envs list from questions json data = json.load(open(args.questions_json, 'r')) qns = data['questions'] if args.env_id is None: envs = sorted(list(set(qns.keys()))) else: envs = [args.env_id] random.shuffle(envs) invalid = [] count_path_found = 0 count_valid = 0 count_path_not_found = 0 count_no_source_cands = 0 shortest_path_lengths = [] for h in tqdm(envs): # `scn2scn` from suncg-toolbox segfaults for this env :/ if h == '436d655f24d385512e1e782b5ba88c6b': continue for q in qns[h]: logging.info("count_path_found: {}".format(count_path_found)) logging.info("count_valid: {}".format(count_valid)) logging.info( "count_path_not_found: {}".format(count_path_not_found)) logging.info( "count_no_source_cands: {}".format(count_no_source_cands)) if len(shortest_path_lengths) > 0: logging.info( "shortest path length mean: {}, median: {}, min: {}, max: {}" .format(np.mean(shortest_path_lengths), np.median(shortest_path_lengths), np.min(shortest_path_lengths), np.max(shortest_path_lengths))) logging.info("env, question pair: {}_{}".format(h, q['id'])) logging.info("{} {} {}".format(h, q['question'], q['answer'])) env = Environment(api_thread, h, cfg, ColideRes=args.map_resolution) h3d = House3DUtils( env, graph_dir=args.graph_dir, target_obj_conn_map_dir=args.target_obj_conn_map_dir, build_graph=False) if os.path.exists( os.path.join(args.shortest_path_dir, "{}_{}.pkl".format(h, q['id']))): logging.info("Shortest path exists") continue # set target object bbox_obj = [ x for x in q['bbox'] if x['type'] == 'object' and x['target'] is True ][0] obj_id = [] for x in h3d.objects: if all([h3d.objects[x]['bbox']['min'][i] == bbox_obj['box']['min'][i] for i in range(3)]) and \ all([h3d.objects[x]['bbox']['max'][i] == bbox_obj['box']['max'][i] for i in range(3)]): obj_id.append(x) if h3d.objects[x]['fine_class'] != bbox_obj['name']: logging.info('Name not matched {} {}'.format( h3d.objects[x]['fine_class'], bbox_obj['name'])) assert len(obj_id) == 1 bbox_room = [ x for x in q['bbox'] if x['type'] == 'room' and x['target'] is False ][0] target_room = False for room in h3d.env.house.all_rooms: if all([room['bbox']['min'][i] == bbox_room['box']['min'][i] for i in range(3)]) and \ all([room['bbox']['max'][i] == bbox_room['box']['max'][i] for i in range(3)]): target_room = room break target_obj = obj_id[0] h3d.set_target_object(h3d.objects[target_obj], target_room) # sample a close enough target point target_point_cands = np.argwhere((env.house.connMap >= 0) & (env.house.connMap <= 5)) target_point_idx = np.random.choice(target_point_cands.shape[0]) target_yaw, best_coverage = h3d._get_best_yaw_obj_from_pos( target_obj, [ target_point_cands[target_point_idx][0], target_point_cands[target_point_idx][1] ], height=1.0) target_point = (target_point_cands[target_point_idx][0], target_point_cands[target_point_idx][1], target_yaw) # graph creation used for selecting a source point t1 = time() if os.path.exists( os.path.join( h3d.graph_dir, h3d.env.house.house['id'] + '_' + target_obj + '.pkl')): print('loading graph') h3d.load_graph( os.path.join( h3d.graph_dir, h3d.env.house.house['id'] + '_' + target_obj + '.pkl')) else: print('building graph') h3d.build_graph(save_path=os.path.join( h3d.graph_dir, h3d.env.house.house['id'] + '_' + target_obj + '.pkl')) connmap_values = env.house.connMap.flatten() connmap_values.sort() # threshold for --source_candidate_fraction number of points thresh = connmap_values[int( (1.0 - args.source_candidate_fraction) * connmap_values.shape[0])] source_point_cands = np.argwhere((env.house.connMap != -1) & (env.house.connMap >= thresh)) if thresh < 50: # sanity check to prevent scenario when agent is spawned close to target location logging.info("No source candidates") invalid.append(h) count_no_source_cands += 1 continue t2 = time() logging.info("Time spent for graph creation {:.6f}s".format(t2 - t1)) for it in range(10): logging.info("Try: {}".format(it)) try: source_point_idx = np.random.choice( source_point_cands.shape[0]) source_point = (source_point_cands[source_point_idx][0], source_point_cands[source_point_idx][1], np.random.choice(h3d.angles)) # A* for shortest path t3 = time() target_x, target_y, target_yaw = target_point source_continous = h3d.env.house.to_coor(source_point[0], source_point[1], shft=True) target_continous = h3d.env.house.to_coor(target_x, target_y, shft=True) points_queue = [] distances_source = dict() prev_pos = dict() distances_source[source_point] = 0 prev_pos[source_point] = (-1.0, -1.0, -1.0, -1.0, -1.0) # schema for point in points_queue: # (x-grid-location, y-grid-location, yaw, x-continous-coordinate, y-continous-coordinate) source_point = (source_point[0], source_point[1], source_point[2], source_continous[0], source_continous[1]) heappush(points_queue, (heuristic_estimate( source_continous, target_continous), source_point)) while True: if len(points_queue) == 0: count_path_not_found += 1 logging.info("A* not able to find path to target") raise ValueError( "Path not found to target {} {}".format( source_point[:3], target_point)) f_dist, point = heappop(points_queue) add_neighbors(h3d, points_queue, point, distances_source, prev_pos, target_continous) if point[0] == target_x and point[ 1] == target_y and point[2] == target_yaw: # store path shortest_path_nodes = [] while True: shortest_path_nodes.append(point) point = prev_pos[point[:3]] if point[0] == -1: break shortest_path_nodes.reverse() break t4 = time() logging.info( "Time spent for coupled graph generation and A*: {:.6f}s" .format(t4 - t3)) # bookkeeping act_q, pos_q, coord_q, actual_q = [], [], [], [] episode_images = [] movemap = None for i in range(len(shortest_path_nodes) - 1): u = shortest_path_nodes[i] v = shortest_path_nodes[i + 1] pos_q.append( (float(u[3]), 1.0, float(u[4]), float(u[2]))) coord_q.append(h3d.env.house.to_grid(u[3], u[4])) curr_x, curr_y, curr_yaw = u[3], u[4], u[2] next_x, next_y, next_yaw = v[3], v[4], v[2] if curr_yaw != next_yaw: if next_yaw == 171 and curr_yaw == -180: act_q.append(1) elif next_yaw == -180 and curr_yaw == 171: act_q.append(2) elif next_yaw < curr_yaw: act_q.append(1) else: act_q.append(2) else: act_q.append(0) pos_q.append((shortest_path_nodes[-1][3], 1.0, shortest_path_nodes[-1][4], shortest_path_nodes[-1][2])) act_q.append(3) if args.check_validity: h3d.env.reset(x=pos_q[0][0], y=pos_q[0][2], yaw=pos_q[0][3]) h3d_yaw = pos_q[0][ 3] # dummy yaw limited to [-180, 180) actual_q.append( (float(h3d.env.cam.pos.x), 1.0, float(h3d.env.cam.pos.z), float(h3d.env.cam.yaw))) for i, action in enumerate(act_q[:-1]): pre_pos = [ h3d.env.cam.pos.x, h3d.env.cam.pos.z, h3d.env.cam.yaw ] img, _, episode_done = h3d.step(action) episode_images.append(img) post_pos = [ h3d.env.cam.pos.x, h3d.env.cam.pos.z, h3d.env.cam.yaw ] actual_q.append((float(h3d.env.cam.pos.x), 1.0, float(h3d.env.cam.pos.z), float(h3d.env.cam.yaw))) if all([ np.abs(pre_pos[x] - post_pos[x]) < 1e-9 for x in range(3) ]): raise ValueError("Invalid action") angle_delta = post_pos[2] - pre_pos[2] h3d_yaw = (h3d_yaw + 180 + angle_delta) % 360 - 180 assert np.abs(h3d.env.cam.pos.x - pos_q[i + 1][0]) < 1e-3 assert np.abs(h3d.env.cam.pos.z - pos_q[i + 1][2]) < 1e-3 assert h3d_yaw == pos_q[i + 1][3] count_valid += 1 movemap = h3d.env.house._showMoveMap(visualize=False) logging.info("Valid") result = { "actions": act_q, "actual_q": actual_q, "answer": q['answer'], "coordinates": coord_q, "images": episode_images, "movemap": movemap, "positions": pos_q, "question": q['question'], } with open( os.path.join(args.shortest_path_dir, "{}_{}.pkl".format(h, q['id'])), "wb") as f: pickle.dump(result, f) logging.info("Saved {}_{}.pkl".format(h, q['id'])) logging.info("Length of shortest path: {}".format( len(shortest_path_nodes))) shortest_path_lengths.append(len(shortest_path_nodes)) count_path_found += 1 break except KeyboardInterrupt: raise except: invalid.append("env, question pair: {}_{}".format( h, q['id'])) traceback.print_exc()
def _load_envs(self, start_idx=-1, in_order=False): #self._clear_memory() if start_idx == -1: start_idx = self.env_set.index(self.pruned_env_set[-1]) + 1 # Pick envs self.pruned_env_set = self._pick_envs_to_load( split=self.split, max_envs=self.max_threads_per_gpu, start_idx=start_idx, in_order=in_order) if len(self.pruned_env_set) == 0: return # Load api threads start = time.time() if len(self.api_threads) == 0: for i in range(self.max_threads_per_gpu): self.api_threads.append( objrender.RenderAPIThread(w=224, h=224, device=self.gpu_id)) self.cfg = load_config('../../House3D/tests/config.json') print('[%.02f] Loaded %d api threads' % (time.time() - start, len(self.api_threads))) start = time.time() # Load houses from multiprocessing import Pool _args = ([h, self.cfg, self.map_resolution] for h in self.pruned_env_set) with Pool(len(self.pruned_env_set)) as pool: self.all_houses = pool.starmap(local_create_house, _args) print('[%.02f] Loaded %d houses' % (time.time() - start, len(self.all_houses))) start = time.time() # Load envs self.env_loaded = {} for i in range(len(self.all_houses)): print('[%02d/%d][split:%s][gpu:%d][house:%s]' % (i + 1, len(self.all_houses), self.split, self.gpu_id, self.all_houses[i].house['id'])) environment = Environment(self.api_threads[i], self.all_houses[i], self.cfg) self.env_loaded[self.all_houses[i].house['id']] = House3DUtils( environment, target_obj_conn_map_dir=self.target_obj_conn_map_dir, build_graph=False) # [TODO] Unused till now self.env_ptr = -1 print('[%.02f] Loaded %d house3d envs' % (time.time() - start, len(self.env_loaded))) # Mark available data indices self.available_idx = [ i for i, v in enumerate(self.env_list) if v in self.env_loaded ] # [TODO] only keeping legit sequences # needed for things to play well with old data temp_available_idx = self.available_idx.copy() for i in range(len(temp_available_idx)): if self.action_lengths[temp_available_idx[i]] < 5: self.available_idx.remove(temp_available_idx[i]) print('Available inds: %d' % len(self.available_idx)) # Flag to check if loaded envs have been cycled through or not # [TODO] Unused till now self.all_envs_loaded = False
def worker(): api_thread = objrender.RenderAPIThread(w=224, h=224) while True: i, house_id, qns = q.get() print('Processing house[%s] %s/%s' % (house_id, i+1, len(house_to_qns))) env = Environment(api_thread, house_id, cfg, ColideRes=args.colide_resolution) h3d = House3DUtils(env, build_graph=False, graph_dir=args.graph_dir, target_obj_conn_map_dir=args.target_obj_conn_map_dir) # compute shortest path for each qn for qn in qns: tic = time.time() samples = [] for _ in range(args.num_samples): sample = {'shortest_paths': [], 'positions': []} if qn['type'] in ['object_color_compare_inroom', 'object_color_compare_xroom', 'object_size_compare_inroom', 'object_size_compare_xroom']: ntnp = '2obj4p' # 2 objects assert len(qn['bbox']) == 2 obj1_id, obj2_id = qn['bbox'][0]['id'], qn['bbox'][1]['id'] obj1_name, obj2_name = qn['bbox'][0]['name'], qn['bbox'][1]['name'] # 4 points try: source_point, obj1_point, obj2_point, end_point, obj1_iou, obj2_iou = get_4points_for_2objects(h3d, obj1_id, obj2_id, args) except: print('4 points for 2 objects not found.') continue # compute shortest paths try: ordered = True positions, actions = sample_paths(h3d, [source_point, obj1_point, obj2_point, end_point]) samples.append({'positions': positions, 'actions': actions, 'best_iou': {obj1_name: obj1_iou, obj2_name: obj2_iou}, 'ordered': ordered}) except: print('shortest path not found for question[%s](%s).' % (qn['id'], qn['type'])) continue elif qn['type'] == 'object_dist_compare_inroom': ntnp = '3obj5p' # 3 objects assert len(qn['bbox']) == 3 obj1_id, obj2_id, obj3_id = qn['bbox'][0]['id'], qn['bbox'][1]['id'], qn['bbox'][2]['id'] obj1_name, obj2_name, obj3_name = qn['bbox'][0]['name'], qn['bbox'][1]['name'], qn['bbox'][2]['name'] # 5 points try: source_point, obj1_point, obj2_point, obj3_point, end_point, obj1_iou, obj2_iou, obj3_iou = \ get_5points_for_3objects(h3d, obj1_id, obj2_id, obj3_id, args) except: print('5 points for 3 objects not found.') continue # compute shortest paths try: ordered = True positions, actions = sample_paths(h3d, [source_point, obj1_point, obj2_point, obj3_point, end_point]) samples.append({'positions': positions, 'actions': actions, 'best_iou': {obj1_name: obj1_iou, obj2_name: obj2_iou, obj3_name: obj3_iou}, 'ordered': ordered}) except: print('shortest path not found for question[%s](%s).' % (qn['id'], qn['type'])) continue elif qn['type'] == 'room_size_compare': ntnp = '2rm4p' # 2 rooms assert len(qn['bbox']) == 2 room1_id, room2_id = qn['bbox'][0]['id'], qn['bbox'][1]['id'] # 4 points try: source_point, room1_point, room2_point, end_point = get_4points_for_2rooms(h3d, room1_id, room2_id, args) except: print('4 points for 2 rooms not found.') continue # compute shortest paths try: ordered = True positions, actions = sample_paths(h3d, [source_point, room1_point, room2_point, end_point]) samples.append({'positions': positions, 'actions': actions, 'ordered': ordered}) except: print('shortest path not found for question[%s][%s].' % (qn['id'], qn['type'])) continue # save if len(samples) == 0: invalid.append(qn['id']) # do not use += here! else: print('%s [%s] samples for question[%s] in %.2fs.' % (len(samples), ntnp, qn['id'], time.time()-tic)) fname = [str(qn['house'])] + [str(box['id'])for box in qn['bbox']] fname = '.'.join(fname) + '.json' with open(osp.join(args.shortest_path_dir, fname), 'w') as f: json.dump(samples, f) # finished this job q.task_done()