반응형

 



global selectObject = $selection
global vColor

rollout Pos2VertexColor "Pos2VertexColor" width:380 height:330
(
	button Pos2VertexColor_Btn "Pos2VertexColor" width:123  height:34
	--button PivotCheck_Btn "PivotCheck" width:123  height:34
	button UnitSetup_Btn "UnitSetup" width:123  height:34
	button VertexColor_Check_Btn "VertexColorCheck" width:123  height:34

	
	fn Pos2VertexColor =
	(
		if selectObject != undefined then
		(
			for m =1 to  selectObject.count do
			(								
				a = selectObject[m]
				setCommandPanelTaskMode #modify
				subObjectLevel =1
				
 			-- avoid minus value
				MeshPivot  = (a.pivot+50)*0.1

				for i=1 to a.verts.count do
				(
					a.EditablePoly.Setselection #Vertex #{i}
					a.setVertexColor (color MeshPivot[1] MeshPivot[2] MeshPivot[3] ) #vertexcolor
					vColor = a.getVertexColor #vertexcolor
									
				)
				print  vColor
				
				 
			)
		)
	
		if $ == undefined then
		(
			messagebox "please select Object"
		)	
	)
	
	fn get2VertexColor =
	(
		if selectObject != undefined then
		(
			a = selectObject 
			getVertColor a 1
	
			
			
			
		)
	)
			
		
	fn timeCheck = 
	(
		t=timeStamp()
		format "%ms\n" (timeStamp()-t)
	)
		

	on Pos2VertexColor_Btn pressed do 
	(
		Pos2VertexColor()
		timeCheck()
	)
	
	
	on VertexColor_Check_Btn pressed do 
	(
		get2VertexColor()
		timeCheck()
		
	)
	

)
createdialog Pos2VertexColor








 

반응형

'Script > MaxScript' 카테고리의 다른 글

FBX EXPORTER & Anim for Unity  (0) 2020.05.07
pos2zero  (0) 2019.10.11
Random_Scatter_Surface  (0) 2019.10.11
TRI,VERTEX Viewport Count  (0) 2019.10.11
반응형
#-*-coding:utf-8 -*-
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4 import *
import sys
import unreal
import glob

actor_list = []
actor_count=[]
classtype = [unreal.StaticMeshActor, unreal.SkeletalMeshActor, unreal.PostProcessVolume,
             unreal.SphereReflectionCapture, unreal.DirectionalLight, unreal.LightmassImportanceVolume
    , unreal.PlayerStart]

class Test2(QtGui.QMainWindow):


    def __init__(self): #Method #self는 객체의 인스턴스 그자체.

        #3.0이상 버전에서 super().__init__()
        # 다른 메소스에서 변수 사용할려면 self붙임.
        super(QtGui.QMainWindow, self).__init__()#3.0이상 버전에서 super().__init__()
        #self.setupUi()
        self.tableUi()
        self.resize(1000,500)
        self.move(150,150)

        btn1 = QtGui.QPushButton("getLevelActor", self)
        btn1.move(250, 0)
      #  btn1.clicked.connect(self.)

    def tableUi(self):

        self.boxLayout = QtGui.QVBoxLayout()
        self.boxLayout2 = QtGui.QVBoxLayout()

        self.treeWidget = QtGui.QTreeWidget(self)
        self.label = QtGui.QLabel("Label")
        self.boxLayout.addWidget(self.treeWidget)
        self.boxLayout.addWidget(self.label)
        self.treeWidget.resize(1000,500)
        self.treeWidget.setHeaderLabel("HeaderLabel")
        self.toplevelList = []
        self.toplevelitem =[]

        actor_count = self.get_actors_count_level()
        self.actors = unreal.EditorLevelLibrary.get_all_level_actors()

        childitem = []  #--- 액터를 담을 아이템
        childlevelList =[]  #-- 버튼으로 보여줄 각각의 액터.

        # 아래 넣어줄 toplevelList[] 의 값
        for z in range(len(classtype) - 1):
            self.toplevelList.append(QtGui.QLabel())  # --- 리스트에 라벨 추가할떄마다 아래 값을 대입.
            self.toplevelList[z] = QtGui.QLabel(str(classtype[z]) + str(actor_count[z].values()))

        for s in range(len(classtype)-1):
            actor_by_class = unreal.EditorFilterLibrary.by_class(self.actors, classtype[s])
            self.toplevelitem.append(QtGui.QTreeWidgetItem())  # -- QTreeWidgetItem 리스트에 추가.
            self.treeWidget.addTopLevelItem(self.toplevelitem[s])  # -- QTreeWidgetItem 비어있는 아이템을 Toplevel에 추가.
            self.treeWidget.setItemWidget(self.toplevelitem[s], 0, self.toplevelList[s]) # -- QTreeWidgetItem[]에 toplevelList[]의 값을 넣어줌.

            for i in range(len(actor_by_class)):
                childitem.append(QtGui.QTreeWidgetItem())  # -- childitem용 QTreeWidgetItem 리스트에 추가.
                self.toplevelitem[s].addChild(childitem[i]) # -- 각각의 Toplevel item에 비어있는 아이템을 액터수만큼 생성.

                childlevelList.append(QtGui.QPushButton()) # -- QPushButton 리스트에 추가.
                childlevelList[i] = QtGui.QPushButton(str(actor_by_class[i])) # -- 각각의 액터클래스이름을 받아서 버튼을 리스트로
                self.treeWidget.setItemWidget(childitem[i], 0, childlevelList[i]) # -- childitem에다가 위 버튼 값을 넣어줌

            # init list -- 이 코드 없어서 리스트 제대로 안나오는걸 하루넘게 못 잡음.ㅠㅠ
            del childitem[:]


    def chilsDes(self):
        print"clicked"

        #테이블 에디터 금지.
    #    self.table.setEditTriggers(QtGui.QTableWidget.NoEditTriggers)

      #  self.table.setHorizontalHeaderLabels([U"코드", U"설정"])
      #  self.table.cellDoubleClicked.connect(self.cell_was_clicked)

    def table2Ui(self):
        self.table1 = QtGui.QTableWidget(self)
        self.table1.move(0, 0)
        self.table1.resize(200, 200)
        print"xxxxxxxxxxxxxxxxxxxxxxxx"

    #  self.table.cellDoubleClicked.connect(self.cell_was_clicked)

    def setupUi(self):
        self.setWindowTitle( "title")
        self.resize(500, 880)
        self.move(400,0)

        btn1 = QtGui.QPushButton("getLevelActor", self)
        btn2 = QtGui.QPushButton(U"임포트", self)
        btn3 = QtGui.QPushButton(U"LOD갯수", self)
        btn4 = QtGui.QPushButton("ClickMe", self)
        btn5 = QtGui.QPushButton(U"레벨 정보 얻기", self)

        btn1.move(50,50)
        btn2.move(150, 50)
        btn3.move(150, 100)
        btn4.move(150, 150)
        btn5.move(250, 50)

        btn1.clicked.connect(self.table_set_item)



    # --- 클래스 이름과 클래스를 사용하고 있는 액터 갯수.
    def get_class_count(self, class_name):
        actors = unreal.EditorLevelLibrary.get_all_level_actors()

        # --- 클래스로 리스트안에서 선택.
        actor_by_class = unreal.EditorFilterLibrary.by_class(actors, class_name)
        # --- 이름과 수를 딕셔너리로 저장.
        class_count = {class_name:len(actor_by_class)}
        actor_count.append(class_count)
        return actor_by_class
    # --- 지정한 클래스 타입에 따라 실행하고 난뒤 최종 리스트값(actor_count)을 반환.
    def get_actors_count_level(self):
        for i in classtype:
            self.get_class_count(i)
        return actor_count



    def get_class(self, actor, class_name):
        if actor.static_class() == class_name.static_class():
            actor_array = {actor.get_actor_label(): str(actor.static_class())}
            actor_list.append(actor_array)

    def get_all_actors_Level(self):
        # --- 리스트안의 데이타만 삭제.(초기화)
        del actor_list [:]

        actors = unreal.EditorLevelLibrary.get_all_level_actors()
        classtypecount = len(classtype)

        for i in actors:
            for s in range(0, classtypecount):
                self.get_class(i, classtype[s] )
        return actor_list

    # --- 테이블 아이템 세팅.
    def table_set_item(self):
        # --- 레벨상 액터들 정보값을 리턴 받는다
        actor_list = self.get_all_actors_Level()
        actor_count = self.get_actors_count_level()
        print actor_count
       # actor_list.sort()
        actor_list_lens = len(actor_list)

        # --- 액터들 갯수에 따라 행렬 갯수 구분(데이타 정보에 따라 수정)
        self.table.setRowCount(len(classtype))
        #self.table.setRowCount(actor_list_lens)
        self.table.setColumnCount(len(actor_list[0]) + 2)


        # --- 정해진 액터 리스트별 값들을 테이블에 넣어준다.
        for i in range(0, len(classtype)):
       # for i in range(0, actor_list_lens):
            # --- actor_list[] #액터 리스트안 i번째 딕셔너리의 키값 가져오기
            actor_list_key = str(actor_list[i].keys())
            actor_list_count = str(actor_count[i].values())
            actor_list_name = str(actor_count[i].keys())

            # --- 액터리스트중 키값을 데이타로 받는 아이템 생성.
            items = QtGui.QTableWidgetItem(actor_list_key)
            items_count = QtGui.QTableWidgetItem(actor_list_count)
            items_list = QtGui.QTableWidgetItem(actor_list_name)
            # --- 생성된 아이템을 테이블에 set
            self.table.setItem(i, 0, items_list)
            self.table.setItem(i, 1, items_count)
        self.table.itemDoubleClicked.connect(self.cell_was_clicked)



    def cell_was_clicked(self):
        tree_item = QtGui.QTreeWidgetItem("aaaaaa")

        tree_widget = QtGui.QTreeWidget(self)
        tree_widget.addTopLevelItem(tree_item)

        layout = QtGui.QStringListModel()

        self.setLayout(layout)




        # actor_list_key = str(actor_list[i].keys())
        # items = QtGui.QTableWidgetItem(actor_list_key)
        row = self.table.currentRow()
        col = self.table.currentColumn()

        print("Row %d and Col %d was Clicked" %(row, col))




          #  self.table.setItem(i, 2, items)


    def testme(self):
        print"aaaaaaaaaaaaaaaaaa"
    # layout = QtGui.QGridLayout()
    # layout.addWidget(self.table,0,0)
    # self.setLayout(layout)


    def get_Num_Verts(Mesh, lod_index=0):
        if Mesh == unreal.SkeletalMesh:
            verts = unreal.EditorSkeletalMeshLibrary.get_num_verts(Mesh, lod_index)
        if Mesh == unreal.StaticMesh:
            verts = unreal.EditorStaticMeshLibrary.get_num_verts(Mesh, lod_index)



        print verts




    def success_Message(self):
        Qbox = QtGui.QMessageBox
       # Qbox.setGeometry(self, 30, 300, 2000, 10)

        Qbox.about(self, "message", U"완료하였습니다.")



app= None
if not QtGui.QApplication.instance():
    app=QtGui.QApplication(sys.argv)

dialog = Test2() # dialog = 객체를 생성할땐 생성자를 사용., 인스턴스(해당 클래스의 구조로 컴퓨터 저장공간에서 할당된 실체)
dialog.show()

#app.exec_()  -- 이벤트 루프 생성.
반응형

'Script > Python' 카테고리의 다른 글

Python - 3Dsmax 스크립트관리 및 뷰어.  (0) 2020.05.07
반응형

파이참, Pyqt4, Qt-Designer 사용.

 

  1. 초기 스크립트 위치 폴더 지정하면, c:\temp에 위치 경로파일 생성.
  2. 지정한 폴더내의 맥스 스크립트를 불러와서
  3. 목록 구성후
  4. 해당 파일 더블클릭하면 스크립트 실행됨.
  5. 설명 및 아이콘은 파이썬 코드에서 수정.

 

 

####################################
######## created by 김진규 #########
####################################
from PyQt4.QtGui import * # https://www.lfd.uci.edu/~gohlke/pythonlibs/pyqt4
from PyQt4 import uic
from PyQt4.QtCore import QSize
import MaxPlus
import glob
import sys, os

RootPath = os.path.dirname(__file__).replace('\\','/')
mainuipath = RootPath+'/ui/ScriptViewer.ui'  # --- QT디자이너 파일 위치.
scriptPath = 'c:/temp/ms_config.txt' # --- 스크립트 config파일 생성.
model = QStandardItemModel()
stringmodel =QStringListModel()

item_list = [U"1번을 할 수 있는 스크립트 입니다.",
             U"2번을 만드는 스크립트 입니다.",
             U"3번을 생성하는 스크립트 입니다.",
             U"4번을 할까말까 하는 스크립트 입니다."]
iconlist = [RootPath+"/1.png", RootPath+"/2.png", RootPath+"/3.png"]

app = QApplication.instance()
if not app:# PySide using QtGui.QApplication(), 3ds Max, there is already a PySide application running, so you get a handle for that object like this:
   app = QApplication([])

# https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__developer_using_pyside_html
class _GCProtector(object): # ---- To protect widgets from being garbage collected
    widgets = []

class Script_Viewer(QMainWindow):
    def __init__(self):
        super(Script_Viewer, self).__init__() # ---https://pystock.atlassian.net/wiki/spaces/FIN/pages/393342/4+-+PyQt
        #QMainWindow.__init__(self)
        _GCProtector.widgets.append(QMainWindow)
        uic.loadUi(mainuipath,self)  #---uic.loadUi essentially loading the widget name into the classes namespace.

        self.init_setup()
        self.Config()
        self.Button01.clicked.connect(self.button)
        self.DirPath_bt.clicked.connect(self.DirectoryPath)
        self.listView_01.doubleClicked.connect(self.excuteMaxScript)
        self.listView_01.clicked.connect(self.Script_Des)

    def Config(self):
        try: # --- 파일 열어서 첫번째 라인 읽고 표시
            config_file = open(scriptPath, 'r')
            line = config_file.readline().decode('utf-8') # --- 한글 경로 불러올시 UTF8로 디코딩.
            self.textEdit.setText(line)
            return line
        except: # --- 파일 없으면 파일 생성후 닫기(디렉토리 웹에서 붙여넣기하면 에러남)
            config_file = open(scriptPath, 'w')
            config_file.close()
            print U"세팅값이 없음."
            return None

    def init_setup(self):
        self.setWindowTitle("ScriptViewer")
        self.move(10, 10)  # ---윈도우창 위치.
        self.setStyleSheet("background-color: white;")
        # --- 디렉토리 다시 선택 할 필요없게 스크립트안에 디렉토리 위치 있으면 실행
        if self.Config: # --- if len(self.Config()) > 1:
            self.getfilelist()

    def button(self):
        QMessageBox.about(self, "message", U"클릭.") #---U 한글깨져서 유니코드 사용.
        print("clicked")

    def DirectoryPath(self):
        targetDir_Ms =unicode (QFileDialog.getExistingDirectory(self, "Select Directory")) #유니코드로 변환후 인/디코딩.

        # --- 디렉토리 선택창 그냥 닫을때 null 오류방지.
        if targetDir_Ms:
            # ---윈도우 슬래쉬 교체.
            targetDir_Ms = targetDir_Ms.replace('\\','/')
            self.textEdit.setText(targetDir_Ms)

            # ---디렉토리 위치 파일에 저장.
            config_file = open(scriptPath, 'w')
            config_file.write(targetDir_Ms.encode('utf-8')) # --- 한글 경로 저장시 UTF8로 인코딩.
            config_file.close()

            self.getfilelist()
            return targetDir_Ms
        else:
            QMessageBox.about(self, "message",  U"파일을 선택하지 않았습니다.")
            print(U"선택되지 않음.")

    def getDirPath(self):
        # --- 설정값 있으면
        if self.Config :
            targetDir = self.Config()
        else:
            targetDir = self.DirectoryPath()
        return targetDir

    def getfilelist(self):
        # --- 기존 목록삭제(중복방지)
        model.clear()
        targetDir = self.getDirPath()
        fileList = sorted(glob.glob(targetDir + "/*.ms")) # --- 파일명으로 정렬 #, key=os.path.getatime)
        print fileList
        view =  self.listView_01

        for file in fileList:
            # --- 스크립트파일명만 보이게 하기위해.
            file = file.split('\\')
            file_item = QStandardItem(file[-1]) # --- 마지막 문자열 선택
            file_item.setSizeHint(QSize(0,50)) # --- 리스트 사이즈

            # --- 아이콘 세팅. https://doc.qt.io/qt-5/qicon.html
            # icon.pixmap(QSize(80, 80)) #--- 일단 여기선 조정 안되고 QT디자이너에서 크기 결정.
            x = model.rowCount()
            icon = QIcon()
            empty_icon =RootPath+"/empty_icon.png"

            if x > len(iconlist)-1:# --- 아이콘 갯수가 스크립트 수보다 적을때(아이콘이 없을때)
                iconlist.append(empty_icon)
            icon.addPixmap(QPixmap(iconlist[x]), QIcon.Normal, QIcon.On)
            file_item.setIcon(icon)

            model.appendRow(file_item)
        view.setModel(model)
        model_Item_Num = model.rowCount()
        print(U'스크립트 개수는 : ' + str(model_Item_Num))

    def Script_Des(self, index):#index에서 넘버링 왜 나오는지는 아직 모르겠네.
        item_num = index.row()#---row  넘버링.
        item_index = model.itemFromIndex(index) #---인덱스로 아이템 구해오기.
        item_text = QStandardItem.text(item_index)#--- 해당 아이템을 텍스트로 가져오기.

        if item_num > len(item_list) -1 :  #---item_num은 0시작 = len(item_list) - 1
            self.textBrowser.setText(U"스크립트에 대한 설명이 없습니다.")
        else : # --- 리스트에서 해당 인덱스 번호의 스크립트 설명 가져오기.
            item_description = item_list[item_num]
            self.textBrowser.setText(item_description)
        return str(item_text)

    def excuteMaxScript(self, index):
        # --- 스크립트 주소
        targetDir = self.getDirPath()

        # --- 스크립트 경로와 스크립트 이름 합침.
        item_text1 = targetDir +"/" + self.Script_Des(index)
        scriptfile = "fileIn" + '"'+ item_text1 +'"'
        try: # --- 맥스에서 맥스스크립트 실행
            MaxPlus.Core.EvalMAXScript(scriptfile)
        except RuntimeError:
            print(U"스크립트가 정상 동작 하지 않습니다.")

# def main():
#    app = QApplication(sys.argv)
#    app = QApplication.instance()
#    if not app:# PySide using QtGui.QApplication(), 3ds Max, there is already a PySide application running, so you get a handle for that object like this:
#        app = QApplication([])
#
#    main = Script_Viewer()
#    main.show()
#    sys.exit((app.exec_()))

if __name__ == '__main__':
    # main()
   main = Script_Viewer()
   main.show()

 
반응형

'Script > Python' 카테고리의 다른 글

UE4 에디터 유형별 에셋 및 기타 기능 WIP  (0) 2020.05.20
반응형

FBX 익스포트 (2017버전 기준)

  1. 스킨적용된 메쉬 익스포트
  2. 한 파일안의 애니메이션을  특정구간별 익스포트
  3. 마지막으로 선택한 디렉토리 및 모션 값을 저장 하거나 불러오기
  4. 버그수정
    • 모디파이어 패널이 아닐때(skin modifier 못찾는것) selectObj클릭시 오류수정
    • SelectObj 클릭시 본, 헬퍼 안보이게 한것 수정.
    • selectDir 클릭후 폴더를 선택하지 않고 창을 닫을떄 오류수정
    • FrameStart 최대가 100인것 수정
    • 모션 리스트 없거나 1나만 있을떄 List_컬러체킹용 클릭시 오류수정, 개선
  5. 맥스 뷰포트에서 새로운 창 띄우고 거기에서 정해진 프레임별 애니선택 및 체크 할수 있게 제작
  6. 배치용 익스포트

사용 예시

/*
FBX Export maxscript tool
Copyright (C) 2015-2018, JinKyu Kim
This program is distributed in the hope that it will be useful.

------------------------------------------------------------------------------
-- FBX Export split animation clips in maxfile
-- By Jinkyu Kim (http://chakanz.tistory.com/, contact : chakan0000@gmail.com)
-- Created On: 2015-04-08
-- tested using  Max 2017
-------------------------------------------------------------------------------
*/

global FBX_Export 

try
    (   makedir (   (getdir #scripts) + @"\tmp\") ) catch   (print "error~~~~~~~~~~~~~")
    
    
-- 익스포트될 디렉토리 저장.
    Global inifilepath  =   (getdir #scripts )+ @"\tmp\Export_Setting.ini"

-- 배치용 디렉토리 저장.
    Global iniSourceFilepath    =   (getdir #scripts )+ @"\tmp\SourceFile_Setting.ini"

-- 애니메이션 리스트 저장
    Global aniSettingPath   =   maxfilepath+getFilenameFile maxfilename+ @".ini"
/*  
--  파일이름 관련  예시.
--  file="g:\\subdir1\\subdir2\\myImage.jpg"
--  filenameFromPath file -- returns: "myImage.jpg"
--  getFilenamePath file -- returns: "g:\subdir1\subdir2\"
--  getFilenameFile file -- returns: "myImage"
--  getFilenameType file -- returns: ".jpg"
--  pathIsNetworkPath "c:\\temp\\test.txt" --returns: false
--  pathIsNetworkPath "\\\\someserver\\temp\\test.txt" --returns: true
*/
    
global frame = #()

-- 익스포트할때 각 확장자_타입별 클래스.
global  theClasses = exporterPlugin.classes     

try DestroyDialog FBX_Export catch()


rollout FBX_Export "FBX_EXPORT" width:300 height:700
( 
    Group "OBJ Export"
        (
            button SelectObj        "SelectObj"                 pos:[5,20]          width:140 height:35
            label   showbox         "Select for Export"     pos:[35,65]         width:200 height:50
            button  btn_SelectDir   "SelectDir"                pos:[5,115]     width:50 height:20
            edittext text_SelDir        ""                             pos:[55,115]        width:200 height:20
        )
            button ExportMesh       "ExportMesh"              pos:[5,140]     width:140 height:35
        
    Group "Ani Export"
        (       
            button bt_ExportAni     "ExportAni"                 pos:[5,530]     width:140 height:35
            button bt_LoadAni        "Load"                 pos:[160,530]     width:40 height:35
            button bt_SaveAni        "Save"                 pos:[200,530]     width:40 height:35
            edittext ed_TakeName "TakeName "                pos:[10,200]    width:140 height:15
            spinner sp_FrameStart "FrameStart "                pos:[10,220]             width:200 height:15 range:[0,9000,0]  type:#integer
            spinner sp_FrameEnd  "FrameEnd  "                pos:[10,240]      width:200 height:15  range:[0,9000,0] type:#integer
        
            button  bt_AniAdd       "ADD"                      pos:[5,260]     width:60 height:35
            button  bt_AniRemove "REMOVE"                   pos:[65,260]        width:60 height:35
            button  bt_AniReset     "RESET"                     pos:[125,260]   width:60 height:35
            Label   ed_ItemList "0개의 모션"                   pos:[10,300]        width: 200 height:15
            button  bt_listcolor    "LIST_컬러체킹용"               pos:[200,260]   width:80 height:35

            dotnetControl lv_Object "System.Windows.Forms.ListView" pos:[10,320] width:280 height:200
            Label  ed_empty "" pos:[10,565]  width:140 height:15
        )
        
    Group   "Batch Export"
        (
            button bt_BatchExport   "BatchExport"       pos:[140,630]  width:140 height:35
            button  btn_SourceDir   "SourceDir"         pos:[5,610]     width:50 height:20
            edittext text_SourceDir         ""                    pos:[55,610]    width:200 height:20
            label   created       "Create by Jinkyu kim"     pos:[185,680]         width:200 height:50
        )   
        

            
    fn SelectSkinnedBones = 
    (
--Mesh선택하기 위해서 
        hidebyCategory.helpers = true
        hidebyCategory.bones = true
        max select all      
        
--모디파이 탭 선택되고 스킨안에 포함된 본들을 선택
        max modify mode

--본, 더미 다시 보이게
        hidebyCategory.helpers = false
        hidebyCategory.bones = false
        
        if $ !=undefined  then     
        (   
                SelectMesh = $
                
                if $.modifiers[#Skin] != undefined  do               
                (
                    Tskin = $.modifiers[#Skin] 

--스킨에 적용된 본갯수
                    BoneNum = skinOps.GetNumberBones Tskin                

--배열지정
                    SkinBoneList=#()                                                            

-- 본객수만큼 반복 .
                    for i=1 to BoneNum do  
                    (  
                        
--본 이름을 배열로 넣음                      
                        SkinBoneList[i] = skinOps.GetBoneName Tskin i 1     
                    )
                    
                    clearselection
                    
--본이름 배열 개수만큼반복.
                    for i=1 to SkinBoneList.count do                                     
                    (
                        
--배열값의 이름을 얻어온다.
                        nodeSkinBone = getnodebyname SkinBoneList[i]     
                        if nodeSkinBone !=undefined do
                        (
                            selectmore nodeSkinBone
                            FBX_Export.showbox.text ="모델네임 : "+ SelectMesh.name + "  \n" +"본 개수   : "+SkinBoneList.count as string +"_Bones"
                        )
                    )
                    
                )
        )
    )


    fn SelectDir = 
    (
-- 캡션은 선택창에서 보이는 글적는것.
        Global Target = getSavePath caption:"Keep Working~!!!!!!!!!!!!!!!!!!!!!!!!!! \nSelect Directory for Export"  initialDir:FBX_Export.text_SelDir.text         
        if Target != undefined  then
        (
            FBX_Export.text_SelDir.text = Target        
        )
    )
        
    
    fn SourceDir = 
    (
        Global SourceTarget = getSavePath caption:  "익스포트할 소스폴더를 선택 하세요.!"  initialDir:(getDir #maxroot)    
        if Target != undefined  then
        (
            FBX_Export.text_SourceDir.text = SourceTarget                                                                                   
        )
    )       
            

    fn ExportObj = 
    (               
-- 겟파일네임함수로 맥스파일네임을 가지고 온다.     
        export_name = getFilenameFile maxFileName                                                                                           
        
--처음에 Target를 썻었는데 에러가 뜸. 그래서 직접 FBX_Export.text_SelDir.text  를 넣어줌
--익스포트 클래스 5번째 항목인 FBX로 익스포트. -- "\"이것만 쓰면 영역지정이 안됨. 앞에 @ 붙여주니깐 됨.
        exportFile (FBX_Export.text_SelDir.text + @"\" + export_name)    #noPrompt  using:theClasses[9] selectedOnly:true           
        print (FBX_Export.text_SelDir.text + @"\"  + export_name)                                                                                                       
    )


    fn ExportFBX_Option=
    (
        FBXExporterSetParam "SmoothingGroups" true
        FBXExporterSetParam "Animation" false
        FBXExporterSetParam "Cameras" false
        FBXExporterSetParam "Lights" false
        FBXExporterSetParam "UpAxis" "Y"
        FBXExporterSetParam "ScaleFactor" 1.0
        FBXExporterSetParam "ConvertUnit" "cm"
        FBXExporterSetParam "Skin" true

--FBXExporterSetParam "embed Media" false  --embed Media 체크시 텍스쳐를 포함하는 FBX                                                                            
        FBXExporterSetParam "ASCII" false -- binaries are smaller
    )       

    
    local layout_def = #("", "TakeName", "StartFrame", "EndFrame")

    
    fn initListView lv =  
    (
        lv.gridLines = true
        lv.View = (dotNetClass "System.Windows.Forms.View").Details
        lv.MultiSelect = true
        lv.FullRowSelect=true
        lv.backColor = (dotNetClass "System.Drawing.color").DarkKhaki   
/*      
-- lv.Checkboxes = true
-- lv.LabelEdit = true --리스트아이템의 첫번쨰 열(세로)만 됨.
-- lv.Items.Item[1].backColor =  (dotNetClass "System.Drawing.color").Green
-- lv.Items.Item[1].SubItems.Item[3].backColor =  (dotNetClass "System.Drawing.color").Yellow
*/
        for i in layout_def do    

--layout_def의 배열 값을 하나씩 가져와 가로69인  항목을 추가한다.            
            (lv.Columns.add i 69 ) 
    )


    Local Item = #()
    Local ItemClass =dotNetClass "ListViewItem"
    Local NumF

    
    fn addList lv mNumF mTakenF mStartF mEndF =
    (   
        NumF = mNumF  as string
        TakenF = mTakenF as string
        StartF = mStartF  as string
        EndF = mEndF  as string
        data = #(NumF)
 
-- data의 배열인 i가  아래 4개의 값(i, TakenF, StartF, EndF) )을 모아서 item에 전달.
        item = for i in data collect                                           
        (
            dotNetObject ItemClass  #(i, TakenF, StartF, EndF) 
        )
        lv.items.addRange item
        lv.Update()
    )


    fn ListRemove lv =
    (
        local selitem = #()
        a = lv.SelectedItems
        SelCount = a.Count

        if SelCount !=0 then
        (

-- 선택된 아이템의 갯수만큼 반복한다. 반복할때마다 선택된아이템들 아이템을 수집해서 selitem의 배열에 집어넣는다. (((i-1 은 LISTVIEW 는 0부터 시작. 맥스스크립트는 1부서 시작)))
            selitem = for i=1 to SelCount collect (a.item[i-1])  

--selitem안에 selecteditems을 삭제. 
            for i in selitem do ( lv.items.remove  i)             
        )       
        else messagebox "선택 후 클릭 하십시요~~"
    )       

        
--아이템 위치 확인용        
    fn ListViewColorCheck lv= 
    (
        if  lv.items.count !=0 do
        (
            for i=1 to  lv.items.count do
            (  
--https://developer.mozilla.org/en-US/docs/Web/CSS/color_value--컬러색보는곳
                lv.items.item[i-1].UseItemStyleForSubItems = false
                lv.items.item[i-1].subitems.item[1].backcolor = (dotNetClass "System.Drawing.color").LightPink
                lv.items.item[i-1].subitems.item[2].backcolor = (dotNetClass "System.Drawing.color").darkslateblue
                lv.items.item[i-1].subitems.item[3].backcolor = (dotNetClass "System.Drawing.color").deepskyblue
--  print lv.items.item[0].subitems.item[i].text

                
            )
        )
        
    )

/*
--  global RangeStart = animationRange.start
--  global RangeEnd = animationRange.end
*/

    fn ExportAni lv = 
    (   
        AllCount =   lv.Items.count
        ListArray = #()
               
        for i=1 to AllCount do
        
        (    
            AniName =  lv.items.item[i-1].SubItems.item[1].text
            FStart =   lv.items.item[i-1].Subitems.item[2].text
            FEnd   =   lv.items.item[i-1].Subitems.item[3].text
            _AniName    = AniName as string
            _FStar      =  FStart as integer
            _FEnd       = FEnd as integer

-- 배열을 배열에 집어 넣음.
            append ListArray #(_AniName,    _FStar, _FEnd)                            
        )
  
-- 배열안의  1번쨰 배열을 선택해서 세개의 값을 가져갈수 있도록
        for m in ListArray do                                                                  
        (   
                animationRange = interval m[2] m[3]
                FBXExporterSetParam "Animation" true 
                FBXExporterSetParam "BakeAnimation" true 
                FBXExporterSetParam "BakeFrameStart"    m[2] 
                FBXExporterSetParam "BakeFrameEnd"   m[3]
                FBXExporterSetParam "BakeFrameStep" 1.0
-- FbxExporterSetParam "BakeResampleAnimation" true
-- FbxExporterSetParam "NormalsPerPoly" false
-- FBXExporterSetParam "SplitAnimationIntoTakes" m[1] m[2] m[3]  -- #(_AniName,    _FStar, _FEnd)   --2011 버전은 없는거 같음.
                FBXExporterSetParam "Cameras" false
                FBXExporterSetParam "Lights" false
                FBXExporterSetParam "UpAxis" "Y"
                FBXExporterSetParam "ScaleFactor" 1.0
                FBXExporterSetParam "ConvertUnit" "cm"
                FBXExporterSetParam "Skin" true
                FBXExporterSetParam "ASCII" false -- binaries are smaller
                export_name = getFilenameFile maxFileName
--  FBXExporterSetParam "embed Media" false           
            
-- 처음에 Target를 썻었는데 에러가 뜸. 그래서 직접 FBX_Export.text_SelDir.text  를 넣어줌.           
                exportFile (FBX_Export.text_SelDir.text + @"\" + export_name+"_" + m[1])    #noPrompt using:theClasses[9]   selectedOnly:true   --using:theClasses[9] 맥스 버전에 따라 다름., using:FBXEXP 써도 되나봄

-- exportFile(Target + @"\" + export_name + m[1])  #noPrompt selectedOnly:boolSelOnly using:exporterPlugin.classes[intFBXID]
--  FBXExporterSetParam "SplitAnimationIntoTakes" "-c"      -- [TakeName] StartValue EndValue  값초기화.        
        )               
    )

    
--최근 위치값 설정 저장.
    fn SaveInifile _path=
    (
        setINISetting _path  "SelectedDir"  "Export_Dir"     text_SelDir.text 
    )

    
--최근 위치값 설정 불러오기..
    fn LoadInifile _path=
    (
        text_SelDir.text    =   getINISetting _path  "SelectedDir"  "Export_Dir"    
    )

    
--최근 소스파일 위치값 설정 저장.
    fn SaveIniSourcefile _path=
    (
        setINISetting _path  "SourceDir"    "_Dir"   text_SourceDir.text 
    )

    
--최근 소스파일 위치값 설정 불러오기..
    fn LoadIniSourcefile _path=
    (
        text_SourceDir.text     =   getINISetting _path  "SourceDir"    "_Dir"  
    )


--애니 설정값 저장.
    fn SaveAni_Inifile _path=
    (
--저장시 이전 기록 삭제.(기존 기록 유지시 데이타 꼬임)   
        delINISetting _path "Animation"

-- 단순히 애니파일 구분하기위한 용도.
        null = "---------------"    
        
        for i= 1 to  lv_Object.items.count do
        (
            setINISetting _path  " Animation"   (null+ i as string)                 "Take"  
            setINISetting _path  " Animation"   ("AniName" + i as string)   lv_Object.items.item[i-1].SubItems.item[1].text
            setINISetting _path  " Animation"   ("FStart"   +i as string)       lv_Object.items.item[i-1].Subitems.item[2].text
            setINISetting _path  " Animation"   ("FEnd" +i as string )         lv_Object.items.item[i-1].Subitems.item[3].text
        )
            setINISetting _path  " Animation"   (null as string)                        "Total "  
            setINISetting _path  " Animation" "Count"  (lv_Object.items.count as string)
    )


--애니 설정값 불러오기.
    fn LoadAni_Inifile _path=
    (   
        for i= 1 to getINISetting _path  " Animation" "Count" as integer do
        (
            TakeName    =   getINISetting _path  " Animation"   ("AniName"  + i as string ) 
            FrameStart  =   getINISetting _path  " Animation"   ("FStart"       +i as string)   
            FrameEnd    =   getINISetting _path  " Animation"   ("FEnd"         +i as string )  
            NumF = "선택"
            addList lv_Object NumF TakeName FrameStart FrameEnd --위 라인에서 설정한 값들을 addlist(Listview에 숫자 넣는 함수) 함수에서 실행.       
        )                       
            FBX_EXPORT.ed_ItemList.Text=  getINISetting _path  " Animation" "Count" as string +"개의 모션 "   
    )


    fn ListReset  lv =
    (
        lv.items.clear()
    )

    
--ListView 아이템 갯수
    fn listNum lv =        
    (   
        lv.items.count
    ) 
    
        
    on FBX_Export open do
    (
        print "\--------------------------------------------------------------------"
        print "open"
        try(LoadInifile inifilepath)catch()
        LoadIniSourcefile iniSourceFilepath
        initListView lv_Object
        print  inifilepath
    )   

    
    on FBX_Export close do
    (
        SaveInifile inifilepath 
        SaveIniSourcefile iniSourceFilepath
        print "\--------------------------------------------------------------------"
        print "closed"          
    )

    
    on SelectObj pressed do
    (
        SelectSkinnedBones()
    )    

    
    on btn_SelectDir pressed do
    (
        SelectDir ()
    )
    
            
    on btn_SourceDir pressed do
    (
        SourceDir  ()
    )
    
    
    on bt_SaveAni pressed do
    (
        SaveAni_Inifile aniSettingPath
    )

    
    on bt_LoadAni pressed do
    (
        
--로딩전에 리스트 리셋하기 
        ListReset lv_Object
        LoadAni_Inifile aniSettingPath
    )
    
    
    on ExportMesh pressed do
        
    (
        ExportFBX_Option()  
        ExportObj()
    )


    on bt_ExportAni pressed do
        
    (   
        ExportAni lv_Object      
    )


    local NumCount = #()
        
    
    on bt_AniAdd pressed do 
    (
        NumF = "선택"
        local TakeName =  FBX_EXPORT.ed_TakeName.Text
        local FrameStart = FBX_EXPORT.sp_FrameStart.value
        local FrameEnd =  FBX_EXPORT.sp_FrameEnd.value
            
        if (FrameStart > FrameEnd) then
        messagebox "시작 값이 끝나는값보다 작아야 됩니다."
        
        else
        (
--위 라인에서 설정한 값들을 addlist 함수에서 실행.
            addList lv_Object NumF TakeName FrameStart FrameEnd 

--입력값 초기화
            TakeName =  FBX_EXPORT.ed_TakeName.Text=""             
            FrameStart =  FBX_EXPORT.sp_FrameStart.value=0
            FrameEnd  =  FBX_EXPORT.sp_FrameEnd.value=0
            FBX_EXPORT.ed_ItemList.Text=   listNum lv_Object as string  +"개의 모션 "   
        )
    )
        
    
    on bt_BatchExport pressed do
    (
--파일에 @가 포함이면   
        bAniFile        = matchpattern maxfilename pattern:     @"*@*"      

--파일에 Mesh가 포함이면                
        bMeshFile   = matchpattern maxfilename pattern:     @"*Mesh*"           
        
        maxfiles=#()
        maxfiles    =   getFiles ( text_SourceDir.text + "\*.max")
        
        for f in maxfiles do 
        (

--  loadMaxFile() will replace the current scene content with the file content without warning!     
            loadmaxfile f           

-- 셀렉트 스킨메쉬.            
            SelectSkinnedBones()
            
--  export 메쉬
            if(bMeshFile == true) then          
                (
                    ExportFBX_Option()  
                    ExportObj()
                )
-- export 애니                
            if(bAniFile == true) then               
            (
--  LoadAni_Inifile  각각의 애니셋팅 목록값을 불러온다.
                LoadAni_Inifile aniSettingPath  
                ExportAni lv_Object                     
            )   
        )
    )


    on bt_AniReset pressed do
    (
        ListReset lv_Object
--ADD버튼을 누릴떄마다 넘버가 늘어나는데 리셋후에도 계속 늘어나 코드 추가.    
        NumCount = #()    
        FBX_EXPORT.ed_ItemList.Text=   listNum lv_Object as string  +"개의 모션 "
    )
        

    on bt_AniRemove pressed do
    (
                ListRemove lv_Object
                FBX_EXPORT.ed_ItemList.Text=   listNum lv_Object as string  +"개의 모션 "
    )
        

    on bt_listcolor pressed do
    (
        ListViewColorCheck  lv_Object
    )

)

createdialog FBX_Export

 

 

 

 

FBX_Export_split_animationClips_in_maxfile.ms

 

drive.google.com

 

반응형

'Script > MaxScript' 카테고리의 다른 글

Pos2VertexColor for Foliage Animation wip  (0) 2020.06.19
pos2zero  (0) 2019.10.11
Random_Scatter_Surface  (0) 2019.10.11
TRI,VERTEX Viewport Count  (0) 2019.10.11
반응형

캐릭터별 

  • 캐릭터 전용 스크립트 적용
  • 스크립트에 넣어야하는 Bone/socket 자동추가
  • 쉐이더및 공용 텍스쳐 자동추가

 

 

 

악세사리

  • 파츠네이밍에따른스크립트자동추가

 

반응형
반응형

오브젝트의 x,y 볼륨의 중심이 0,0으로 가고 높이는 최하위 버텍스 기준으로 0으로 이동.

objcet_pos2zero.ms
다운로드

 

 

 

 global exportsetup

 rollout chReset "chRest" width:340 height:200 
 ( 
     button bt_Pick "1. Pick" pos:[10,20] width:120 height:30
     GroupBox group1 "result" pos:[50,90] width:150 height:70
     label showbox "대기" pos:[60,120] width:100 height:30
     button bt_chReset "2. chReset" pos:[10,50] width:120 height:30

     on bt_Pick pressed do
     (
         p=pickobject prompt: "Pick Mesh"
         if p!=undefined then
         (
           select p
           p.wirecolor= [255,20,30,1]
           chReset.showbox.text= "선택했습니다" 
         )
         else
         (
            chReset.showbox.text= " 선택하세요" 
         )

     )

     on bt_chReset  pressed do
     (
         mPlane=Plane length:1 width:1 name:"AlignTarget" pos:[0,0,0] 
         ---오브젝트가 2개 이상일때 오류남
         select $
         deselect mPlane 
         SelObj=$ --선택된 오브젝트를 Selobj라 명명
         CenterPivot(SelObj) --피봇을 선택된 오브젝트의 중심으로 설정
         vpos = for i in SelObj.verts collect i.pos.z
         --버택수를 배열로 넣어서 그중에서 최대 최소 포지션 값을 구함
         
         vmax= amax vPos
         vmin= amin vPos
         move SelObj [-$.center.x,-$.center.y,- vmin] 
         --오브젝트를 0,0,0 에서 벗어난 만큼 빼줘서 0,0,0위치로 오게끔 설정
         
         SelObj.Pivot=[0,0,0] --오브젝트의 피봇 위치를 설정
         ResetXForm SelObj
         maxOps.CollapseNode $ off ---CollapseAll
         delete mPlane
         chReset.showbox.text= " 이동했습니다"  

     )

 )

 createDialog chReset



 

반응형

'Script > MaxScript' 카테고리의 다른 글

Pos2VertexColor for Foliage Animation wip  (0) 2020.06.19
FBX EXPORTER & Anim for Unity  (0) 2020.05.07
Random_Scatter_Surface  (0) 2019.10.11
TRI,VERTEX Viewport Count  (0) 2019.10.11
반응형

 

 

Random_Scatter_Surface.ms
다운로드

수정후 - 이미 생성된 곳의 폴리곤을 지워서 한번 생성된 자리에서는 다시 생성안되게~

 

 

 

수정전 - 무조건 랜덤생성

 

 

 

 

mBase = copy $  --선택된 바닥을 카피
mBase.wirecolor = color 88 88 255

delete $

select mBase

FaceNum = polyop.getNumFaces mBase  --선택된 오브제의 총 면수 
Farray = for obj in mBase.Faces collect obj.index --선택된 오브제의 면을 수집해서 Farray에 배열로 넣음
PercentCount = FaceNum*0.1 -- 폴리 선택 (현재는 전체폴리의 10%값)

GetNum=#()  --배열 설정.q

for j=1 to PercentCount do  --PercentCount 번동안  Farray의 배열중에 랜덤 반복선택해서 GetNum에 넣음. 
(
	 GetNum[j] = Farray [random 1 FaceNum]
)

GetNum  

-- subobjectLevel = 4
polyop.setFaceSelection mBase GetNum

for t=1 to PercentCount do  --선택된 폴리만큼 오브젝트 복사.이동
(
   m = copy $source
   m.pos=  polyop.getsafefacecenter $ GetNum[t]
   m.dir = polyop.getFaceNormal $ GetNum[t]
   m.wirecolor= orange
)

polyop.deleteFaces mBase GetNum --선택된 폴리를 지움.

반응형

'Script > MaxScript' 카테고리의 다른 글

Pos2VertexColor for Foliage Animation wip  (0) 2020.06.19
FBX EXPORTER & Anim for Unity  (0) 2020.05.07
pos2zero  (0) 2019.10.11
TRI,VERTEX Viewport Count  (0) 2019.10.11
반응형

 

Global GW_displayText

unregisterRedrawViewsCallback GW_displayText

fn GW_displayText=
(
    obj = selection --¿ÀºêÁ§Æ® ¼±ÅÃ

    if obj!=0 then
    (
         for i=1  to obj.count do -- ¿ÀºêÁ§Æ®¼±ÅÃÇÑ ¼ö ¸¹Å­ ¹Ýº¹
        (

            tricount=(getTrimeshFaceCount obj[i])[1]  
            vertcount=(getTrimeshFaceCount obj[i])[2]
            objname=obj[i].name 

             wPos=gw.getWinsizeX()/2
             gw.wtext[wPos-100,50,0] "TRICOUNT" color:red
             gw.wtext[wPos,50*i,0] objname[i] color:red
             gw.wtext[wPos+100,50*i,0](tricount as string+" TRI") color:red
             gw.wtext[wPos+100,50*i+20,0](vertcount as string+" VERTEX") color:red

        )
     )
) 


registerRedrawViewsCallback GW_displayText
-- a= getTrimeshFaceCount $
-- a[1]
-- a[2]

 

반응형

'Script > MaxScript' 카테고리의 다른 글

Pos2VertexColor for Foliage Animation wip  (0) 2020.06.19
FBX EXPORTER & Anim for Unity  (0) 2020.05.07
pos2zero  (0) 2019.10.11
Random_Scatter_Surface  (0) 2019.10.11

+ Recent posts