def pack_manager_result_handler(self, task, result): global packer new_result = False if self.result_array[task.id] is None: self.result_count += 1 new_result = True self.result_array[task.id] = result # self.scenario.send_out_islands([result.islands, result.non_packed_islands]) if self.result_count < len(self.tasks): return assert (self.result_count == len(self.tasks)) if new_result: self.scenario.send_out_islands( [result.islands for result in self.result_array] + [result.non_packed_islands for result in self.result_array], send_transform=True) else: self.scenario.send_out_islands( [result.islands, result.non_packed_islands], send_transform=True) if self.log_result_area: area_sum = 0.0 for result in self.result_array: area_sum += result.islands.area() packer.send_log(LogType.INFO, "New result area: {}".format(area_to_string(area_sum)))
def run(self): if not self.pack_manager.runconfig.heuristic_search_enabled(): for warn in self.HEURISTIC_WARNINGS: packer.send_log(LogType.WARNING, warn) self.pack_params.grouping_compactness = self.g_scheme.group_compactness pack_task = PackTask(0, self.pack_params) stage_params = StageParams() box = self.target_boxes[0] stage_target = StdStageTarget() stage_target.append(box) group_islands = [ group.islands for group in self.g_scheme.groups if group.islands is not None ] stage_params.pack_groups_together = len(group_islands) > 1 pack_task.add_stage(stage_params, stage_target, group_islands, self.static_islands) self.pack_manager.add_task(pack_task) return self.pack_manager.pack()
def validate_locking(self): for group in self.groups: if group.islands is None: continue for island in group.islands: if island.parent_count < 2: continue parents = island.parents parent_groups = set() for parent in parents: parent_groups.add(parent.get_iparam( self.group_iparam_desc)) if len(parent_groups) > 1: packer.send_log( LogType.WARNING, 'Islands from two different groups were locked together!' ) packer.send_log( LogType.WARNING, 'In result some islands will be processed as not belonging to the groups they were originally assigned to' ) return
def run(self): split_offset_iparam_name = self.cx.params['split_offset_iparam_name'] split_offset_iparam_desc = self.iparams_manager.iparam_desc( split_offset_iparam_name) processed = IslandSet() moved_count = 0 for island in self.cx.selected_islands: split_offset = island.get_iparam(split_offset_iparam_desc) if split_offset < 0: raise InputError( "Split data not available for all selected islands") if split_offset > 0: processed_island = island.offset(-split_offset, 0.0) moved_count += 1 else: processed_island = island processed_island.set_iparam(split_offset_iparam_desc, split_offset_iparam_desc.default_value) processed.append(processed_island) split_offset_iparam_desc.mark_dirty() packer.send_out_islands(processed, send_transform=True, send_iparams=True) packer.send_log(LogType.STATUS, "Done. Islands moved: {}".format(moved_count)) return RetCode.SUCCESS
def handle_invalid_topology(self, invalid_islands): flag_islands(self.cx.input_islands, invalid_islands) packer.send_log(LogType.STATUS, "Topology error") packer.send_log( LogType.ERROR, "Islands with invalid topology encountered (check the selected islands)" )
def run(self): packer.send_log(LogType.STATUS, "Looking for similar islands...") simi_islands = self.cx.selected_islands.find_similar( self.simi_params, self.cx.unselected_islands) for island in simi_islands: island.set_flags(IslandFlag.SELECTED) packer.send_out_islands(simi_islands, send_flags=True) packer.send_log( LogType.STATUS, "Done. Similar islands found: {}".format(len(simi_islands))) return RetCode.SUCCESS
def run(self): packer.send_log(LogType.STATUS, "Similar islands aligning...") aligned_islands = self.cx.selected_islands.align_similar( self.simi_params) send_kwargs = { 'send_vertices' if self.simi_params.correct_vertices else 'send_transform': True } packer.send_out_islands(aligned_islands, **send_kwargs) packer.send_log( LogType.STATUS, "Done. Islands aligned: {}".format(len(aligned_islands))) return RetCode.SUCCESS
def run(self): # area = self.cx.selected_islands.area() eps = 1.0e-9 avg_scale_ratio = 0.0 valid_count = 0 for island in self.cx.unselected_islands: area = island.faces_area() area_3d = island.faces_3d_area() if area < eps or area_3d < eps: continue ratio = area_3d / area avg_scale_ratio += ratio valid_count += 1 if valid_count == 0: packer.send_log( LogType.STATUS, 'No valid unselected island found - adjustment could not be made' ) return RetCode.SUCCESS avg_scale_ratio /= valid_count out_islands = IslandSet() for island in self.cx.selected_islands: area = island.faces_area() area_3d = island.faces_3d_area() if area < eps or area_3d < eps: continue scale = math.sqrt(area_3d / avg_scale_ratio / area) out_islands.append( island.scale(scale, scale, island.bbox().center())) packer.send_out_islands(out_islands, send_transform=True) packer.send_log(LogType.STATUS, "Done") return RetCode.SUCCESS
def init_log_method(self): heuristic_search_time = self.runconfig.heuristic_search_time hint_str = None if heuristic_search_time >= 0: self.log_result_area = True hint_str = self.HEURISTIC_HINT if heuristic_search_time > 0: self.start_time = time.time() # self.time_left = float(heuristic_search_time) self.log_method = self.heuristic_search_time_log else: self.log_method = self.heuristic_search_log else: self.log_method = self.standard_log if hint_str is not None: packer.send_log(LogType.HINT, hint_str)
def run(self): islands_to_check = self.cx.selected_islands overlapping = overlapping_islands(islands_to_check, islands_to_check)[0] overlapping.set_flags(IslandFlag.OVERLAPS) flag_islands(islands_to_check, overlapping) ret_code = RetCode.NOT_SET if len(overlapping) > 0: ret_code = RetCode.WARNING log_msg = 'Overlapping islands detected (check selected islands)' else: ret_code = RetCode.SUCCESS log_msg = 'No overlapping islands detected' packer.send_log(LogType.STATUS, log_msg) return ret_code
def exec(self): ret_code = RetCode.NOT_SET try: self.init() self.pre_run() ret_code = self.run() self.post_run(ret_code) except InputError as err: packer.send_log(LogType.ERROR, str(err)) packer.send_log(LogType.STATUS, 'Invalid operation input') return RetCode.INVALID_INPUT except InvalidIslandsError as err: return RetCode.INVALID_ISLANDS except OpCancelledException: return RetCode.CANCELLED return ret_code
def pack(self): self.result_array = [None] * len(self.tasks) self.result_count = 0 self.runconfig.asyn = True self.runconfig.realtime_solution = True self.runconfig.set_result_handler(pack_manager_result_handler, self) self.init_log_method() for task in self.tasks: packer.run_task(task, self.runconfig) all_tasks_completed = False while not all_tasks_completed: log_str, time_to_wait = self.log_method() packer.send_log(LogType.STATUS, log_str) all_tasks_completed = packer.wait_for_all_tasks(time_to_wait) ret_code = RetCode.NOT_SET self.packed_islands = IslandSet() self.invalid_islands = IslandSet() for task in self.tasks: assert (task.result is not None) result = task.result ret_code = append_ret_codes(ret_code, result.ret_code) if result.ret_code == RetCode.INVALID_ISLANDS: self.invalid_islands += result.invalid_islands if solution_available(result.ret_code): self.packed_islands += result.islands return ret_code
def run(self): split_offset_iparam_name = self.cx.params['split_offset_iparam_name'] split_offset_iparam_desc = self.iparams_manager.iparam_desc( split_offset_iparam_name) offset_step = 1 for island in self.cx.selected_islands: island.metadata = SplitMetadata() processed = IslandSet() to_process = self.cx.selected_islands.clone() while len(to_process) > 0: to_check = to_process.clone() to_check += processed o_map = to_check.overlapping_map() # eprint(o_map) overlapping_islands = [] for island in to_check: island.overlapping = o_map[island] if len(island.overlapping) == 0: if not island.metadata.processed: island.metadata.processed = True processed.append(island) continue if island.metadata.processed: island.metadata.local_offset = 0 continue island.metadata.local_offset = None overlapping_islands.append(island) overlapping_islands.sort( key=lambda island: len(island.overlapping)) to_process.clear() for island in overlapping_islands: free_offset = None offset_to_check = 0 while True: offset_found = True for other_island in island.overlapping: if other_island.metadata.local_offset is not None and other_island.metadata.local_offset == offset_to_check: offset_found = False break if offset_found: free_offset = offset_to_check break offset_to_check += offset_step # max_offset = max(max_offset, free_offset) island.metadata.local_offset = free_offset island.metadata.split_offset += free_offset if free_offset != 0: to_process.append(island.offset(free_offset, 0.0)) else: to_process.append(island) assert (len(processed) == len(self.cx.selected_islands)) moved_count = 0 for island in processed: split_offset = island.metadata.split_offset if split_offset > 0: moved_count += 1 island.set_iparam(split_offset_iparam_desc, split_offset) # if max_offset <= SplitOffsetParamInfo.MAX_VALUE: # undo_possible = True # for island in self.islands: # island.set_param(SplitOffsetParamInfo, island.split_offset) # else: # undo_possible = False # for island in self.islands: # island.set_param(SplitOffsetParamInfo, SplitOffsetParamInfo.INVALID_VALUE) split_offset_iparam_desc.mark_dirty() packer.send_out_islands(processed, send_transform=True, send_iparams=True) packer.send_log(LogType.STATUS, "Done. Islands moved: {}".format(moved_count)) return RetCode.SUCCESS
def run(self): area = self.cx.selected_islands.area() packer.send_log( LogType.STATUS, "Selected islands area: {}".format(area_to_string(area))) return RetCode.SUCCESS