예제 #1
0
    def open_collada_wizard(self):
        def cancel_import():
            self.wizard.request_destroy()

        def confirm_import():
            self.do_import = True
            self.wizard.request_destroy()

        self.wizard = SWindow(
            title='Collada Import Options', modal=True,
            sizing_rule=1)(SVerticalBox()(
                ue.create_detail_view(self.ImportOptions),
                auto_height=True,
                padding=10)(
                    SHorizontalBox()(SButton(
                        text='Cancel',
                        on_clicked=cancel_import,
                        h_align=EHorizontalAlignment.HAlign_Center))(SButton(
                            text='Import',
                            on_clicked=confirm_import,
                            h_align=EHorizontalAlignment.HAlign_Center)),
                    auto_height=True,
                    padding=4,
                ), )
        self.wizard.add_modal()
def show():
    #Data
    saveDir = r"\\vietsap002\projects\R6\04_WIP\tools\perforce\proxyCheck"
    rootDir = ue.get_content_dir()
    matchType = compile(r'\.uasset\Z')
    allstaticmeshes = ue.get_assets_by_class("StaticMesh")
    uassetfolders = ((root,files) for root, subdirs, files in os.walk(rootDir)
        if any(matchType.search(file) for file in files))
    filterstaticmeshfolder = ((folder, list(
            staticmesh for staticmesh in allstaticmeshes
            if any(match("^{}".format(staticmesh.get_name()), ufile) for ufile in ufiles )))
        for folder, ufiles in uassetfolders)
    staticmeshfolder = ((folder, files) for folder, files in filterstaticmeshfolder if files)
    #UI
    window = SWindow().resize(512,1024).set_title("Export Static Mesh")
    vertical = SVerticalBox()
    #style = ButtonStyle(Normal=SlateBrush(TintColor=SlateColor(SpecifiedColor=FLinearColor(1, 0, 0))))
    #picker = SFilePathPicker(browse_title='Export To', browse_button_style=style, on_path_picked=path_picked)
    button = SButton().set_content(STextBlock().set_text("Export All").set_v_align(2)
    vertical.add_slot(button, v_align=0, h_align=0)
    vertical.add_slot(STextBlock().set_text("Export Folders:"), v_align=0, h_align=0)
    vertical.add_slot(picker, v_align=0, h_align=0)
    vertical.add_slot(STextBlock().set_text("Static Mesh Folders:"), v_align=0, h_align=0)
    for folder, ufiles in staticmeshfolder:
        button = SButton().set_content(STextBlock().set_text(os.path.relpath(folder, rootDir))).set_v_align(2)
        button.bind_on_clicked(partial(export, ufiles, saveDir))
        #vertical.add_slot(button, v_align=2, h_align=2)
        vertical.add_slot(button, v_align=0, h_align=0)
    window.set_content(vertical)
    #window.set_modal(True)
show()
예제 #3
0
    def split_hips(self, animation, bone='Hips'):
        self.choosen_skeleton = None
        # first ask for which skeleton to use:
        self.window = SWindow(title='Choose your new Skeleton', modal=True, sizing_rule=1)(
                     SObjectPropertyEntryBox(allowed_class=Skeleton, on_object_changed=self.set_skeleton)
                 )
        self.window.add_modal()
        if not self.choosen_skeleton:
            raise DialogException('Please specify a Skeleton for retargeting')

        factory = AnimSequenceFactory()
        factory.TargetSkeleton = self.choosen_skeleton
        
        base_path = animation.get_path_name()
        package_name = ue.get_path(base_path)
        object_name = ue.get_base_filename(base_path)

        new_anim = factory.factory_create_new(package_name + '/' + object_name + '_rooted')

        new_anim.NumFrames = animation.NumFrames
        new_anim.SequenceLength = animation.SequenceLength

        # first step is generatin the 'root' track
        # we need to do it before anything else, as the 'root' track must be the 0 one
        for index, name in enumerate(animation.AnimationTrackNames):
            if name == bone:
                data = animation.get_raw_animation_track(index)
                # extract root motion
                root_motion = [(position - data.pos_keys[0]) for position in data.pos_keys]

                # create a new track (the root motion one)
                root_data = FRawAnimSequenceTrack()
                root_data.pos_keys = root_motion
                # ensure empty rotations !
                root_data.rot_keys = [FQuat()]
        
                # add  the track
                new_anim.add_new_raw_track('root', root_data)
                break
        else:
            raise DialogException('Unable to find bone {0}'.format(bone))
           
        # now append the original tracks, but removes the position keys
        # from the original root bone
        for index, name in enumerate(animation.AnimationTrackNames):
            data = animation.get_raw_animation_track(index)
            if name == bone:
                # remove root motion from original track
                data.pos_keys = [data.pos_keys[0]]
                new_anim.add_new_raw_track(name, data)
            else:
                new_anim.add_new_raw_track(name, data)

        new_anim.save_package()
예제 #4
0
def show():
    rootDir = ue.get_content_dir()
    matchType = compile(r'\.uasset\Z')
    folders = (root for root, subdirs, files in os.walk(rootDir) if any(matchType.search(file) for file in files))
    window = SWindow().resize(512,1024).set_title("Export Static Mesh")
    vertical = SVerticalBox()
    vertical.add_slot(STextBlock().set_text("Export Folders:"), v_align=2, h_align=0)
    for folder in folders:
        button = SButton().set_content(STextBlock().set_text(os.path.relpath(folder, rootDir))).set_v_align(2)
        #vertical.add_slot(button, v_align=2, h_align=2)
        vertical.add_slot(button, v_align=0, h_align=0)
    window.set_content(vertical)
    #window.set_modal(True)
예제 #5
0
    def open_collada_wizard(self):

        def cancel_import():
            self.wizard.request_destroy()

        def confirm_import():
            self.do_import = True
            self.wizard.request_destroy()

        self.wizard = SWindow(title='Collada Import Options', modal=True, sizing_rule=1)(
                          SVerticalBox()
                          (
                              ue.create_detail_view(self.ImportOptions),
                              auto_height=True,
                              padding = 10
                          )
                          (
                              SHorizontalBox()
                              (
                                  SButton(text='Cancel', on_clicked=cancel_import, h_align = EHorizontalAlignment.HAlign_Center)
                              )
                              (
                                  SButton(text='Import', on_clicked=confirm_import, h_align = EHorizontalAlignment.HAlign_Center)
                              ),
                              auto_height=True,
                              padding = 4,
                          ),
                          
                      )
        self.wizard.add_modal()
예제 #6
0
SWindow(client_size=(1024, 576), title='DynamicComboBox')\
(
    SBorder(color_and_opacity=FLinearColor(0, 1, 0, 1), border_background_color=SlateColor(SpecifiedColor=FLinearColor(1, 0, 0, 1)))
    (
        SBox(h_align=EHorizontalAlignment.HAlign_Center, v_align=EVerticalAlignment.VAlign_Center)
        (
            SBorder(color_and_opacity=FLinearColor(0, 1, 0, 1), border_background_color=SlateColor(SpecifiedColor=FLinearColor(0, 1, 0, 1)))
            (
                SVerticalBox()
                (
                    STextBlock(text='Hello 1', tool_tip_text='Test Tool Tip')
                )
                (
                    STextBlock(text='Hello 2')
                )
                (
                    dynamic_combo_box.get_widget()
                )
                (
                    SHorizontalBox()
                    (
                        SEditableTextBox(text=lambda: '', on_text_committed=dynamic_combo_box.append),
                        fill_width=0.8
                    )
                    (
                        SButton(text='Ok'),
                        fill_width=0.2
                    )
                )
            )
        )
    )
)
import unreal_engine as ue
from unreal_engine import SFilePathPicker, SWindow, FLinearColor
from unreal_engine.structs import ButtonStyle, SlateBrush, SlateColor

# a style is required for the file picker
style = ButtonStyle(Normal=SlateBrush(TintColor=SlateColor(
    SpecifiedColor=FLinearColor(1, 0, 0))))

window = SWindow(client_size=(576, 576), title='Hello', modal=True)


def path_picked(path):
    print(path)
    window.request_destroy()


picker = SFilePathPicker(browse_title='Hello',
                         browse_button_style=style,
                         on_path_picked=path_picked)
window.set_content(picker)

window.add_modal()
예제 #8
0
    def __init__(self):
        self.window = SWindow(client_size=(680, 530),
                              title='Resource List Check',
                              sizing_rule=0)
        self.hori_0 = SHorizontalBox()
        self.hori_0_0 = SHorizontalBox()
        self.hori_1_0 = SHorizontalBox()
        self.hori_2 = SHorizontalBox()
        self.hori_2_0 = SHorizontalBox()
        #self.hori_3_0 = SHorizontalBox()
        self.vert_0 = SVerticalBox()
        #self.vert_2 = SVerticalBox()
        self.main_vertical = SVerticalBox()

        self.scroll = SScrollBox(orientation=EOrientation.Orient_Vertical)
        self.chk_grid = SGridPanel()

        top_vertical = (0, 0, 0, 0)
        mid_vertical = (0, -400, 0, -390)
        bot_vertical = (0, 390, 0, 0)
        #zero_padding = (0,0,0,0)

        self.newindex = []
        self.newint = []

        self.txt_01 = STextBlock(text='엑셀 테이블 경로 : ')
        self.etb = SEditableTextBox().assign('table_path')

        self.hori_0.add_slot(self.txt_01, fill_width=0.1)
        self.hori_0.add_slot(self.etb, fill_width=0.4)
        self.hori_0.add_slot(SButton(text='...',
                                     fill_width=0.1,
                                     on_clicked=lambda: self.fn_sp()),
                             auto_width=True)
        self.hori_0.add_slot(SButton(text='@',
                                     fill_width=0.1,
                                     on_clicked=lambda: self.fn_test()),
                             auto_width=True)
        self.hori_0_0.add_slot(SBorder()(self.hori_0),
                               padding=top_vertical,
                               v_align=EVerticalAlignment.VAlign_Top)

        self.hori_1_0.add_slot(SBorder()(self.vert_0),
                               padding=mid_vertical,
                               v_align=EVerticalAlignment.VAlign_Fill)

        self.hori_2.add_slot(
            SButton(text='선택리스트 저장-TXT',
                    h_align=2,
                    v_align=2,
                    fill_width=0.1,
                    on_clicked=lambda: fn_sel()))
        self.hori_2.add_slot(
            SButton(text='저장리스트 비교-TXT',
                    h_align=2,
                    v_align=2,
                    fill_width=0.1,
                    on_clicked=lambda: fn_readtext()))
        self.hori_2.add_slot(STextBlock(text='  매칭 리스트 정렬 '),
                             auto_width=True,
                             v_align=EVerticalAlignment.VAlign_Center)
        self.hori_2.add_slot(sort_bool, auto_width=True)
        self.hori_2.add_slot(STextBlock(text='  리스트에 없는 에셋만 표시 '),
                             auto_width=True,
                             v_align=EVerticalAlignment.VAlign_Center)
        self.hori_2.add_slot(checkbox_bool, auto_width=True)
        self.hori_2_0.add_slot(SBorder()(self.hori_2),
                               padding=bot_vertical,
                               v_align=EVerticalAlignment.VAlign_Fill)

        # 초기설정파일 셋팅
        if fn_OpenDefaultSetting() != None:
            table_path.set_text(fn_OpenDefaultSetting())
            #테이블 리스트 함수 - 설정 경로 바탕으로 리스트를 작성 합니다
            if self.fn_resettable() != None:
                self.fn_resettable()
        else:
            ue.log('설정 파일이 없습니다')

        self.main_vertical.add_slot(self.hori_0_0)
        self.main_vertical.add_slot(SBorder()(self.scroll),
                                    padding=mid_vertical,
                                    v_align=EVerticalAlignment.VAlign_Fill)
        self.main_vertical.add_slot(self.hori_2_0)

        self.window.set_content(SBorder()(self.main_vertical))
예제 #9
0
class SetWindow:
    def __init__(self):
        self.window = SWindow(client_size=(680, 530),
                              title='Resource List Check',
                              sizing_rule=0)
        self.hori_0 = SHorizontalBox()
        self.hori_0_0 = SHorizontalBox()
        self.hori_1_0 = SHorizontalBox()
        self.hori_2 = SHorizontalBox()
        self.hori_2_0 = SHorizontalBox()
        #self.hori_3_0 = SHorizontalBox()
        self.vert_0 = SVerticalBox()
        #self.vert_2 = SVerticalBox()
        self.main_vertical = SVerticalBox()

        self.scroll = SScrollBox(orientation=EOrientation.Orient_Vertical)
        self.chk_grid = SGridPanel()

        top_vertical = (0, 0, 0, 0)
        mid_vertical = (0, -400, 0, -390)
        bot_vertical = (0, 390, 0, 0)
        #zero_padding = (0,0,0,0)

        self.newindex = []
        self.newint = []

        self.txt_01 = STextBlock(text='엑셀 테이블 경로 : ')
        self.etb = SEditableTextBox().assign('table_path')

        self.hori_0.add_slot(self.txt_01, fill_width=0.1)
        self.hori_0.add_slot(self.etb, fill_width=0.4)
        self.hori_0.add_slot(SButton(text='...',
                                     fill_width=0.1,
                                     on_clicked=lambda: self.fn_sp()),
                             auto_width=True)
        self.hori_0.add_slot(SButton(text='@',
                                     fill_width=0.1,
                                     on_clicked=lambda: self.fn_test()),
                             auto_width=True)
        self.hori_0_0.add_slot(SBorder()(self.hori_0),
                               padding=top_vertical,
                               v_align=EVerticalAlignment.VAlign_Top)

        self.hori_1_0.add_slot(SBorder()(self.vert_0),
                               padding=mid_vertical,
                               v_align=EVerticalAlignment.VAlign_Fill)

        self.hori_2.add_slot(
            SButton(text='선택리스트 저장-TXT',
                    h_align=2,
                    v_align=2,
                    fill_width=0.1,
                    on_clicked=lambda: fn_sel()))
        self.hori_2.add_slot(
            SButton(text='저장리스트 비교-TXT',
                    h_align=2,
                    v_align=2,
                    fill_width=0.1,
                    on_clicked=lambda: fn_readtext()))
        self.hori_2.add_slot(STextBlock(text='  매칭 리스트 정렬 '),
                             auto_width=True,
                             v_align=EVerticalAlignment.VAlign_Center)
        self.hori_2.add_slot(sort_bool, auto_width=True)
        self.hori_2.add_slot(STextBlock(text='  리스트에 없는 에셋만 표시 '),
                             auto_width=True,
                             v_align=EVerticalAlignment.VAlign_Center)
        self.hori_2.add_slot(checkbox_bool, auto_width=True)
        self.hori_2_0.add_slot(SBorder()(self.hori_2),
                               padding=bot_vertical,
                               v_align=EVerticalAlignment.VAlign_Fill)

        # 초기설정파일 셋팅
        if fn_OpenDefaultSetting() != None:
            table_path.set_text(fn_OpenDefaultSetting())
            #테이블 리스트 함수 - 설정 경로 바탕으로 리스트를 작성 합니다
            if self.fn_resettable() != None:
                self.fn_resettable()
        else:
            ue.log('설정 파일이 없습니다')

        self.main_vertical.add_slot(self.hori_0_0)
        self.main_vertical.add_slot(SBorder()(self.scroll),
                                    padding=mid_vertical,
                                    v_align=EVerticalAlignment.VAlign_Fill)
        self.main_vertical.add_slot(self.hori_2_0)

        self.window.set_content(SBorder()(self.main_vertical))

    # 테이블 버튼 리스트 생성
    def fn_resettable(self):

        table_padding = (10, 5, 10, 5)
        btn_padding = (4, 4, 4, 4)

        # 기본 리스트 설정
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=ctext.tableHeader_01)),
            column=0,
            row=0)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=ctext.listHeader_01)),
            column=1,
            row=0)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=ctext.listHeader_02)),
            column=2,
            row=0)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=ctext.listHeader_03)),
            column=3,
            row=0)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=ctext.listHeader_04)),
            column=4,
            row=0)

        # 테이블에서 엑셀 경로 가져오기
        listxx = fn_Dafultxlsx(table_path.get_text())
        if listxx == None:
            return None
        #ue.log(listxx)

        # 리스트 생성
        for i in range(0, len(listxx)):
            bntlists.append(SetButtontlist(i))

        i = 1
        x = 0

        for ttable in listxx:
            d = i
            name = ttable[0]  #'엑셀파일 이름'
            sname = ttable[1]  #'시트 이름'
            cname = ttable[2]  #'컬럼 이름'
            uesasset = ttable[3]  #'리소스 경로'

            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(
                                               SEditableTextBox(text=str(i))),
                                   column=0,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(STextBlock(text=name)),
                                   column=1,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(STextBlock(text=sname)),
                                   column=2,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(STextBlock(text=cname)),
                                   column=3,
                                   row=i)
            # 버튼 리스트 ADD
            self.chk_grid.add_slot(SBorder(padding=btn_padding,
                                           v_align=2)(bntlists[i - 1].set_bnt),
                                   column=4,
                                   row=i)
            i += 1

        self.scroll.add_slot(self.chk_grid, auto_width=True, auto_hight=True)

    def fn_test(self):
        ue.log('설정테스트')

    # 테이블 경로 - 가져오기
    def fn_sp(self):
        try:
            st = fn_SaveDefaultSetting()
            table_path.set_text(st)
            if self.fn_resettable() != None:
                self.fn_resettable()
        except:
            ue.log('엑셀 기본 경로 설정을 취소 하였습니다')

    # 엑셀 테이블 읽기 위한 필요한 정보 (삭제 해야함
    def fn_tt(self, path, tint):
        datacolumn = fn_Dafultxlsx(path)
        #ue.log(len(datacolumn))
        #ue.log(tint)
        filepath = path + '/' + datacolumn[tint][0] + '.xlsx'
        sheetname = datacolumn[tint][1]
        findcolumn = datacolumn[tint][2]
        addstring = datacolumn[tint][3]
        fn_Loadxlsx(filepath, sheetname, findcolumn, addstring)
예제 #10
0
class RootMotionFixer:

   
    def add_root_to_skeleton(self, mesh, bone='root'):
        base_path = mesh.get_path_name()
        new_path = ue.create_modal_save_asset_dialog('Choose destination path', ue.get_path(base_path), ue.get_base_filename(base_path) + '_rooted')
        if not new_path:
            raise DialogException('Please specify a new path for the Skeletal Mesh copy')
        package_name = ue.object_path_to_package_name(new_path)
        object_name = ue.get_base_filename(new_path)
        # the last True allows for overwrites
        new_mesh = mesh.duplicate(package_name, object_name, True)

        # generate a new skeleton
        new_skel = self.build_new_skeleton(mesh.Skeleton, object_name + '_Skeleton', bone)
        # save the new skeleton in the same package directory of the new skeletal mesh
        new_skel.save_package(package_name)

        # assign the new skeleton to the new mesh
        new_mesh.skeletal_mesh_set_skeleton(new_skel)

        new_skel.save_package()

        self.fix_bones_influences(new_mesh, mesh.Skeleton)

        new_mesh.save_package()

    def build_new_skeleton(self, skeleton, name, root):
        new_skel = Skeleton(name)
        new_skel.skeleton_add_bone(root, -1, FTransform())
        for index in range(0, skeleton.skeleton_bones_get_num()):
            bone_name = skeleton.skeleton_get_bone_name(index)
            bone_parent = skeleton.skeleton_get_parent_index(index)
            bone_transform = skeleton.skeleton_get_ref_bone_pose(index)
            if bone_parent == -1:
                bone_parent_name = root
            else:
                bone_parent_name = skeleton.skeleton_get_bone_name(bone_parent)
            new_bone_parent = new_skel.skeleton_find_bone_index(bone_parent_name)
            new_skel.skeleton_add_bone(bone_name, new_bone_parent, bone_transform)
        return new_skel

    def get_updated_bone_index(self, old_skeleton, new_skeleton, old_bone_map, new_bone_map, index):

        # get the skeleton bone_id from the map
        true_bone_id = old_bone_map[index]

        # get the bone name
        bone_name = old_skeleton.skeleton_get_bone_name(true_bone_id)

        # get the new index
        new_bone_id = new_skeleton.skeleton_find_bone_index(bone_name)

        # check if a new mapping is available
        if new_bone_id in new_bone_map:
            return new_bone_map.index(new_bone_id)

        new_bone_map.append(new_bone_id)
        return len(new_bone_map)-1

    def fix_bones_influences(self, mesh, old_skeleton):
        active_bones = []
        for section in range(0, mesh.skeletal_mesh_sections_num()):
            vertices = mesh.skeletal_mesh_get_soft_vertices(0, section)
            ue.log_warning(len(vertices))
            new_vertices = []
            old_bone_map = mesh.skeletal_mesh_get_bone_map(0, section)
            new_bone_map = []

            for vertex in vertices:
                bone_ids = list(vertex.influence_bones)
                for index, bone_id in enumerate(bone_ids):
                    if vertex.influence_weights[index] > 0:
                        bone_ids[index] = self.get_updated_bone_index(old_skeleton, mesh.Skeleton, old_bone_map, new_bone_map, bone_id)
                        if new_bone_map[bone_ids[index]] not in active_bones:
                            active_bones.append(new_bone_map[bone_ids[index]])
                vertex.influence_bones = bone_ids
                new_vertices.append(vertex)

            # assign new vertices
            mesh.skeletal_mesh_set_soft_vertices(new_vertices, 0, section)
            # add the new bone mapping
            mesh.skeletal_mesh_set_bone_map(new_bone_map, 0, section)

        # specify which bones are active and required (ensure root is added to required bones)
        mesh.skeletal_mesh_set_active_bone_indices(active_bones)
        # mark all the bones as required (eventually you can be more selective)
        mesh.skeletal_mesh_set_required_bones(list(range(0, mesh.Skeleton.skeleton_bones_get_num())))

    def set_skeleton(self, asset_data):
        self.choosen_skeleton = asset_data.get_asset()
        self.window.request_destroy()

    def split_hips(self, animation, bone='Hips'):
        self.choosen_skeleton = None
        # first ask for which skeleton to use:
        self.window = SWindow(title='Choose your new Skeleton', modal=True, sizing_rule=1)(
                     SObjectPropertyEntryBox(allowed_class=Skeleton, on_object_changed=self.set_skeleton)
                 )
        self.window.add_modal()
        if not self.choosen_skeleton:
            raise DialogException('Please specify a Skeleton for retargeting')

        factory = AnimSequenceFactory()
        factory.TargetSkeleton = self.choosen_skeleton
        
        base_path = animation.get_path_name()
        package_name = ue.get_path(base_path)
        object_name = ue.get_base_filename(base_path)

        new_anim = factory.factory_create_new(package_name + '/' + object_name + '_rooted')

        new_anim.NumFrames = animation.NumFrames
        new_anim.SequenceLength = animation.SequenceLength

        for index, name in enumerate(animation.AnimationTrackNames):
            data = animation.get_raw_animation_track(index)
            if name == bone:
                # extract root motion
                root_motion = [position - data.pos_keys[0] for position in data.pos_keys]

                # remove root motion from original track
                data.pos_keys = [data.pos_keys[0]]
                new_anim.add_new_raw_track(name, data)

                # create a new track (the root motion one)
                root_data = FRawAnimSequenceTrack()
                root_data.pos_keys = root_motion
                # ensure empty rotations !
                root_data.rot_keys = [FQuat()]
        
                 # add  the track
                new_anim.add_new_raw_track('root', root_data)
            else:
                new_anim.add_new_raw_track(name, data)

        new_anim.save_package()
예제 #11
0
class ColladaFactory(PyFactory):

    ImportOptions = ColladaImportOptions()

    def __init__(self):
        # inform the editor that this class is able to import assets
        self.bEditorImport = True
        # register the .dae extension as supported
        self.Formats = ['dae;Collada']
        # set the UClass this UFactory will generate
        self.SupportedClass = StaticMesh

    
    def open_collada_wizard(self):

        def cancel_import():
            self.wizard.request_destroy()

        def confirm_import():
            self.do_import = True
            self.wizard.request_destroy()

        self.wizard = SWindow(title='Collada Import Options', modal=True, sizing_rule=1)(
                          SVerticalBox()
                          (
                              ue.create_detail_view(self.ImportOptions),
                              auto_height=True,
                              padding = 10
                          )
                          (
                              SHorizontalBox()
                              (
                                  SButton(text='Cancel', on_clicked=cancel_import, h_align = EHorizontalAlignment.HAlign_Center)
                              )
                              (
                                  SButton(text='Import', on_clicked=confirm_import, h_align = EHorizontalAlignment.HAlign_Center)
                              ),
                              auto_height=True,
                              padding = 4,
                          ),
                          
                      )
        self.wizard.add_modal()


    # this functions starts with an uppercase letter, so it will be visible to the UE system
    # not required obviously, but it will be a good example
    def FixMeshData(self):
        # move from collada system (y on top) to ue4 one (z on top, forward decreases over viewer)
        for i in range(0, len(self.vertices), 3):
           xv, yv, zv = self.vertices[i], self.vertices[i+1], self.vertices[i+2]
           # invert forward
           vec = FVector(zv * -1, xv, yv) * self.ImportOptions.DefaultRotation
           self.vertices[i] = vec.x
           self.vertices[i+1] = vec.y
           self.vertices[i+2] = vec.z
           xn, yn, zn = self.normals[i], self.normals[i+1], self.normals[i+2]
           nor = FVector(zn * -1, xn, yn) * self.ImportOptions.DefaultRotation
           # invert forward
           self.normals[i] = nor.x
           self.normals[i+1] = nor.y
           self.normals[i+2] = nor.z
        
        # fix uvs from 0 on bottom to 0 on top
        for i, uv in enumerate(self.uvs):
            if i % 2 != 0:
                self.uvs[i] = 1 - uv

    def PyFactoryCreateFile(self, uclass: Class, parent: Object, name: str, filename: str) -> Object:
        # load the collada file
        dae = Collada(filename)
        ue.log_warning(dae)

        self.do_import = False
        self.open_collada_wizard()

        if not self.do_import:
            return None


        # create a new UStaticMesh with the specified name and parent
        static_mesh = StaticMesh(name, parent)

        # prepare a new model with the specified build settings
        source_model = StaticMeshSourceModel(BuildSettings=MeshBuildSettings(bRecomputeNormals=False, bRecomputeTangents=True, bUseMikkTSpace=True, bBuildAdjacencyBuffer=True, bRemoveDegenerates=True))

        # extract vertices, uvs and normals from the da file (numpy.ravel will flatten the arrays to simple array of floats)
        triset = dae.geometries[0].primitives[0]
        self.vertices = numpy.ravel(triset.vertex[triset.vertex_index])
        # take the first uv channel (there could be multiple channels, like the one for lightmapping)
        self.uvs = numpy.ravel(triset.texcoordset[0][triset.texcoord_indexset[0]])
        self.normals = numpy.ravel(triset.normal[triset.normal_index])

        # fix mesh data
        self.FixMeshData()
        
        # create a new mesh, FRawMesh is an ptopmized wrapper exposed by the python plugin. read: no reflection involved
        mesh = FRawMesh()
        # assign vertices
        mesh.set_vertex_positions(self.vertices)
        # uvs are required
        mesh.set_wedge_tex_coords(self.uvs)
        # normals are optionals
        mesh.set_wedge_tangent_z(self.normals)
        
        # assign indices (not optimized, just return the list of triangles * 3...)
        mesh.set_wedge_indices(numpy.arange(0, len(triset) * 3))

        # assign the FRawMesh to the LOD0 (the model we created before)
        mesh.save_to_static_mesh_source_model(source_model)

        # assign LOD0 to the SataticMesh and build it
        static_mesh.SourceModels = [source_model]
        static_mesh.static_mesh_build()
        static_mesh.static_mesh_create_body_setup()

        static_mesh.StaticMaterials = [StaticMaterial(MaterialInterface=self.ImportOptions.DefaultMaterial, MaterialSlotName='Main')]

        return static_mesh
예제 #12
0
    def __init__(self, text, textlist, tablename):
        tablenametext = tablename
        self.window = SWindow(client_size=(1024, 600),
                              title='리소스 검색 결과 창' + tablename)
        self.vertical = SVerticalBox()
        self.horizon = SHorizontalBox()
        self.scroll = SScrollBox(orientation=EOrientation.Orient_Vertical)

        self.chk_grid = SGridPanel()
        table_padding = (10, 5, 10, 5)
        btn_padding = (4, 4, 4, 4)
        savepath = ''
        savelist = []

        self.chk_grid.add_slot(SBorder(padding=btn_padding, v_align=2)(SButton(
            text='현재 리스트 TXT 파일로 저장',
            on_clicked=lambda: SaveText(textlist, tablenametext))),
                               column=0,
                               row=0,
                               column_span=2)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=text.tableHeader_01)),
            column=0,
            row=1)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=text.tableHeader_02)),
            column=1,
            row=1)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=text.tableHeader_05)),
            column=2,
            row=1)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=text.tableHeader_04)),
            column=3,
            row=1)
        self.chk_grid.add_slot(
            SBorder(padding=table_padding, h_align=2,
                    v_align=2)(STextBlock(text=text.tableHeader_03)),
            column=4,
            row=1)

        #두번째 row 부터 리스트를 작성 한다.
        i = 2

        for ttable in textlist:  #range(1, 120):
            d = i
            color_val = color_gray
            stringsplit = ttable.split(',')
            name = stringsplit[0]
            path = stringsplit[1]
            assetname = stringsplit[2]
            uesasset = stringsplit[3]

            if '없음' == uesasset:
                color_val = color_red

            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(STextBlock(text=str(i -
                                                                          1))),
                                   column=0,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(STextBlock(text=name)),
                                   column=1,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(STextBlock(
                                               text=uesasset,
                                               color_and_opacity=color_val)),
                                   column=2,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=table_padding,
                                           h_align=2,
                                           v_align=2)(
                                               STextBlock(text=assetname)),
                                   column=3,
                                   row=i)
            self.chk_grid.add_slot(SBorder(padding=btn_padding, v_align=2)(
                SEditableTextBox(text=path)),
                                   column=4,
                                   row=i)

            i += 1

        self.scroll.add_slot(self.chk_grid, auto_width=True, auto_hight=True)
        self.vertical.add_slot(SBorder()(self.scroll),
                               auto_hight=True,
                               padding=5)
        self.window.set_content(self.vertical)
예제 #13
0
from unreal_engine.classes import Blueprint


def clicked(geometry, pointer_event):
    ue.log('Hello')
    ue.log(geometry.fields())
    ue.log(pointer_event.fields())
    return True


def clicked2():
    ue.log('Test')
    return True


window = SWindow().resize(1024, 576).set_title('Hello World')

horizontal = SHorizontalBox()

button = SButton().set_content(STextBlock().set_text('Click ME !'))
button.bind_on_mouse_button_down(clicked)
button.bind_on_clicked(clicked2)

box = SEditableTextBox()

editor = SMultiLineEditableText()
editor.set_text('Hello')

grid = SGridPanel()

grid.add_slot(button, 0, 0)
예제 #14
0
from unreal_engine import SWindow, SButton, SHorizontalBox, FARFilter

# 한글 문자열 수집을 위해 필요함
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

#윈도우 하나만 사용 하자!!! // Error가 있음
#if window != None:
#	window.request_destroy()

window = SWindow(client_size=(330, 32),
                 title='Widget Blueprint To Text',
                 sizing_rule=0)(
                     SHorizontalBox()(SButton(
                         text='전체 WBP 추출', on_clicked=lambda: WBPall()))(
                             # 함수에 연결된 버튼
                             SButton(text='선택한 WBP 추출',
                                     on_clicked=lambda: WBPsel()))(SButton(
                                         text='WBP텍스트 지우기',
                                         on_clicked=lambda: Wtestxx())))


# 테스트설정
def Wtestxx():
    selbp = ue.get_selected_assets()
    for aa in selbp:
        aa.save_package()
        uw = aa.WidgetTree
        allwid = uw.AllWidgets
        for wb in allwid:
            if wb.get_class().get_name() == 'TextBlock':
예제 #15
0
import unreal_engine as ue

from unreal_engine import SWindow, SButton, STextBlock, SEditableTextBox, SMultiLineEditableText, SGridPanel, SHorizontalBox, SPythonEditorViewport
from unreal_engine.classes import Blueprint

def clicked(geometry, pointer_event):
    ue.log('Hello')
    ue.log(geometry.fields())
    ue.log(pointer_event.fields())
    return True

def clicked2():
    ue.log('Test')
    return True

window = SWindow().resize(1024, 576).set_title('Hello World')

horizontal = SHorizontalBox()

button = SButton().set_content(STextBlock().set_text('Click ME !'))
button.bind_on_mouse_button_down(clicked)
button.bind_on_clicked(clicked2)

box = SEditableTextBox()

editor = SMultiLineEditableText()
editor.set_text('Hello')

grid = SGridPanel()

grid.add_slot(button, 0, 0)
from unreal_engine import SWindow, SProgressBar, SButton, SVerticalBox
import unreal_engine as ue

progress_bar = SProgressBar()
canceled = False


def cancel_operation():
    global canceled
    ue.log_warning('slow operation canceled')
    canceled = True


SWindow(title='slow task', sizing_rule=1)(SVerticalBox()(progress_bar)(SButton(
    text='cancel', on_clicked=cancel_operation)))

for i in range(0, 10000):
    progress_bar.set_percent(1 / 10000 * i)
    ue.log('slow task iteration: {0}'.format(i))
    if canceled:
        break
    ue.slate_tick()
import unreal_engine as ue
from unreal_engine import SFilePathPicker, SWindow, FLinearColor
from unreal_engine.structs import ButtonStyle, SlateBrush, SlateColor

# a style is required for the file picker
style = ButtonStyle(Normal=SlateBrush(TintColor=SlateColor(SpecifiedColor=FLinearColor(1, 0, 0))))


window = SWindow(client_size=(576,576), title='Hello', modal=True)

def path_picked(path):
    print(path)
    window.request_destroy()

picker = SFilePathPicker(browse_title='Hello', browse_button_style=style, on_path_picked=path_picked)
window.set_content(picker)

window.add_modal()
예제 #18
0
import unreal_engine as ue
from unreal_engine.classes import StaticMesh
from unreal_engine import SWindow, SScrollBox, SVerticalBox, SHorizontalBox, SImage, STextBlock, FARFilter
from unreal_engine.enums import EPixelFormat

_filter = FARFilter()
_filter.class_names = ['StaticMesh']

thumbnails = []

for static_mesh in ue.get_assets_by_filter(_filter):
    thumbnails.append((static_mesh.get_full_name(), static_mesh.get_thumbnail()))


window = SWindow(client_size=(1024, 512), title='StaticMeshes thumbnails')
scroll_box = SScrollBox()

vertical = SVerticalBox()

for name, thumbnail in thumbnails:
    texture = ue.create_transient_texture(thumbnail.get_image_width(), thumbnail.get_image_height())
    texture.texture_set_data(thumbnail.get_uncompressed_image_data())
    vertical.add_slot(
        SHorizontalBox()
        (
            SImage().set_texture(texture),
            max_width=64
        )
        (
            STextBlock(text=name),
            padding=4,
예제 #19
0
class ColladaFactory(PyFactory):

    ImportOptions = ColladaImportOptions()

    def __init__(self):
        # inform the editor that this class is able to import assets
        self.bEditorImport = True
        # register the .dae extension as supported
        self.Formats = ['dae;Collada']
        # set the UClass this UFactory will generate
        self.SupportedClass = StaticMesh

    def open_collada_wizard(self):
        def cancel_import():
            self.wizard.request_destroy()

        def confirm_import():
            self.do_import = True
            self.wizard.request_destroy()

        self.wizard = SWindow(
            title='Collada Import Options', modal=True,
            sizing_rule=1)(SVerticalBox()(
                ue.create_detail_view(self.ImportOptions),
                auto_height=True,
                padding=10)(
                    SHorizontalBox()(SButton(
                        text='Cancel',
                        on_clicked=cancel_import,
                        h_align=EHorizontalAlignment.HAlign_Center))(SButton(
                            text='Import',
                            on_clicked=confirm_import,
                            h_align=EHorizontalAlignment.HAlign_Center)),
                    auto_height=True,
                    padding=4,
                ), )
        self.wizard.add_modal()

    # this functions starts with an uppercase letter, so it will be visible to the UE system
    # not required obviously, but it will be a good example
    def FixMeshData(self):
        # move from collada system (y on top) to ue4 one (z on top, forward decreases over viewer)
        for i in range(0, len(self.vertices), 3):
            xv, yv, zv = self.vertices[i], self.vertices[i +
                                                         1], self.vertices[i +
                                                                           2]
            # invert forward
            vec = FVector(zv * -1, xv, yv) * self.ImportOptions.DefaultRotation
            self.vertices[i] = vec.x
            self.vertices[i + 1] = vec.y
            self.vertices[i + 2] = vec.z
            xn, yn, zn = self.normals[i], self.normals[i + 1], self.normals[i +
                                                                            2]
            nor = FVector(zn * -1, xn, yn) * self.ImportOptions.DefaultRotation
            # invert forward
            self.normals[i] = nor.x
            self.normals[i + 1] = nor.y
            self.normals[i + 2] = nor.z

        # fix uvs from 0 on bottom to 0 on top
        for i, uv in enumerate(self.uvs):
            if i % 2 != 0:
                self.uvs[i] = 1 - uv

    def PyFactoryCreateFile(self, uclass: Class, parent: Object, name: str,
                            filename: str) -> Object:
        # load the collada file
        dae = Collada(filename)
        ue.log_warning(dae)

        self.do_import = False
        self.open_collada_wizard()

        if not self.do_import:
            return None

        # create a new UStaticMesh with the specified name and parent
        static_mesh = StaticMesh(name, parent)

        # prepare a new model with the specified build settings
        source_model = StaticMeshSourceModel(
            BuildSettings=MeshBuildSettings(bRecomputeNormals=False,
                                            bRecomputeTangents=True,
                                            bUseMikkTSpace=True,
                                            bBuildAdjacencyBuffer=True,
                                            bRemoveDegenerates=True))

        # extract vertices, uvs and normals from the da file (numpy.ravel will flatten the arrays to simple array of floats)
        triset = dae.geometries[0].primitives[0]
        self.vertices = numpy.ravel(triset.vertex[triset.vertex_index])
        # take the first uv channel (there could be multiple channels, like the one for lightmapping)
        self.uvs = numpy.ravel(
            triset.texcoordset[0][triset.texcoord_indexset[0]])
        self.normals = numpy.ravel(triset.normal[triset.normal_index])

        # fix mesh data
        self.FixMeshData()

        # create a new mesh, FRawMesh is an ptopmized wrapper exposed by the python plugin. read: no reflection involved
        mesh = FRawMesh()
        # assign vertices
        mesh.set_vertex_positions(self.vertices)
        # uvs are required
        mesh.set_wedge_tex_coords(self.uvs)
        # normals are optionals
        mesh.set_wedge_tangent_z(self.normals)

        # assign indices (not optimized, just return the list of triangles * 3...)
        mesh.set_wedge_indices(numpy.arange(0, len(triset) * 3))

        # assign the FRawMesh to the LOD0 (the model we created before)
        mesh.save_to_static_mesh_source_model(source_model)

        # assign LOD0 to the SataticMesh and build it
        static_mesh.SourceModels = [source_model]
        static_mesh.static_mesh_build()
        static_mesh.static_mesh_create_body_setup()

        static_mesh.StaticMaterials = [
            StaticMaterial(
                MaterialInterface=self.ImportOptions.DefaultMaterial,
                MaterialSlotName='Main')
        ]

        return static_mesh