예제 #1
0
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)))
예제 #2
0
    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
예제 #4
0
    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)"
        )
예제 #6
0
    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
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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)
예제 #10
0
    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
예제 #12
0
    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
예제 #13
0
    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
예제 #14
0
 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