MAXScript學習筆記(2) JSON

目標:導出struct類型對象爲一個json字符串,並保存到文件中,然後在Unity中讀取。

1.MXSJson(參考:http://www.scriptspot.com/3ds-max/scripts/mxsjson

這個需要再改一下 根據一個struct對象,導出json

獲取struct成員變量信息

測試可以使用

pros=getPropNames per
-- print (pros as string)
for prop in pros do(
    -- print prop
    v=getProperty per prop
    -- print v
)

假如結合這個和MXSJson.ms的話,應該可以得到我想要的,預計要2-3小時開發調試時間吧。繼續找找其他人的,能拿來用的千萬不用自己編寫,原型寫出來很快,維護調試擴展成本很高

2.用C#的Newtonsoft.Json.dll

參考1:https://blog.csdn.net/pengyancai/article/details/50110677#comments

參考2:http://forums.cgsociety.org/t/json-and-maxscript/1552038/11

參考3:http://home.avvanta.com/~loganb/code.htm

其他只是討論一下,這個提供了一個json.ms。可惜沒有例子,要自己摸索使用。

看了一下代碼,是對Newtonsoft.Json.Linq.JObject進行了一下封裝,挺好的,但是要達到我需要的struct2json的效果,還是要二次開發。

3.使用python,(參考:https://forums.autodesk.com/t5/3ds-max-programming/read-json-file/m-p/6769862#M15237

這裏說無法講struct對象傳給c#(參考:https://forums.cgsociety.org/t/struct-as-a-parameter/2047447

4.不用json格式,直接使用struct as string的內容,到c#裏面解析該格式的字符串

看打印出來的內容,有規律,需要的信息也都在

struct TypeInfo(id,type)
struct PersonInfo(name,age,type)
struct BoxInfo(name,count,type)
struct AllInfo(personList,person,box,type)

p=PersonInfo name:"Abc" age:12
print (p as string)
pList=#()
for i= 1 to 2 do
(
    p=PersonInfo name:"Abc" age:i
    p.type=TypeInfo id:i type:("type"+(i as string))
    append pList p
)
print (pList as string)

i=AllInfo()
i.personList=pList
i.person=p
i.box=BoxInfo name:"box" count:20

print (i as string)

打印:

"(PersonInfo name:"Abc" age:12 type:undefined)"
"#((PersonInfo name:"Abc" age:1 type:(TypeInfo id:1 type:"type1")), (PersonInfo name:"Abc" age:2 type:(TypeInfo id:2 type:"type2")))"
"(AllInfo personList:#((PersonInfo name:"Abc" age:1 type:(TypeInfo id:1 type:"type1")), (PersonInfo name:"Abc" age:2 type:(TypeInfo id:2 type:"type2"))) Person:(PersonInfo name:"Abc" age:2 type:(TypeInfo id:2 type:"type2")) Box:(BoxInfo name:"box" count:20 type:undefined) type:undefined)"

----------------

奇怪哦。怎麼沒找到現成的呢。先把業務功能做好,後續再花點時間二次開發一下。

-------------------------

擴展了一下前面的MXSJson,可以直接轉換struct對象了。

struct MXSJson
(
	__keys__ = #(),
	__value__ = #(),
	__isArray__=false, --new
	__array__=#(), --new
	__linebreak__="", --\n有格式,好看一點,"":沒有格式,字符串就一行
	fn format_type value =(
		local f_value = stringstream ""
		
		class_type = classof value

		if superclassof value == StructDef then(

			-- print (classof value)
			format "%" ("{" +value.__json__()+"}") to:f_value
			return f_value as string
			)

		else if class_type == String then(
			format "\"%\"" value to:f_value
			return f_value as string
		)
		
		else if class_type == Integer then(
			format "%" value to:f_value
			return f_value as string
		)
		else if class_type == Array then(
			format "["  to:f_value
			for a in value do(
				l_value = this.format_type a
				
				format_s = "%,"
				if a == value[value.count] do(
					format_s = "%"
					)
				format format_s l_value to:f_value
				)

			format "]" to:f_value	
		)
		else if class_type == UndefinedClass then(
			format "%" "null" to:f_value
			return f_value as string
		)
		else(
			print ("format_type else class :"+(class_type as string))
		)
		return f_value as string
	),
	fn __json__ = (
		data = ""


		for a in __keys__ do(
			item = __value__[finditem __keys__ a]
			data += "\""+ a + "\":"
			end_s = ","+__linebreak__
			if finditem __keys__ a >= __keys__.count do(
				end_s = ""
			)
			if superclassof item == StructDef then(
				data += "{"+item.__json__()+"}"+end_s
				)else(
					-- end_s = ","
					-- if finditem __keys__ a >= __keys__.count do(
					-- 	end_s = ""
					-- )
					
					data += this.format_type(item)+end_s
				)
		)

		return data
	),
	fn __jsonArray__ = (
		data = ""
		for i = 1 to __array__.count do 
		(
			item = __array__[i]
			-- end_s = ","
			end_s = ","+__linebreak__
			if i >= __array__.count do(
				end_s = ""
			)

			if superclassof item == StructDef then(
				data += "{"+item.__json__()+"}"+end_s
				)else(
					data += this.format_type(item)+end_s
					)
		)
		return data
	),
	
	fn json = (
		-- print ("json isArray:"+(__isArray__ as string))
		if __isArray__ == false  then
		(
			return "{"+__linebreak__+ this.__json__()+__linebreak__+"}"
		)
		else
		(
			return "["+ this.__jsonArray__()+"]"
		)
	),
		
	fn items = (
		return this.__keys__
	),

	fn item key =(
		index = finditem this.__keys__ key 
		if index != 0 do(
			return this.__value__[index]
		)
	),
	fn getClassName obj =	( --new
		classInfo=((classof obj) as string)
		parts=FilterString classInfo "("
		n= parts[1]
		-- print ("getClassName:"+n)
		return n
	),

	fn newByStruct structObj = (  --new
		-- try(
			if classof structObj == Array then 
			(
				this.__isArray__=true
				-- __array__
				for i in structObj do
				(
					-- print ("newByStruct array item:"+(i as string))
					mj=MXSJson()
					mj.newByStruct i
					append this.__array__ mj
				)
			)
			else(

				pros=getPropNames structObj
				-- print (pros as string)
				for prop in pros do
				(
					val=getProperty structObj prop
					if classof val == MAXScriptFunction do continue --函數等不要
					this.add prop val
				)
			)

		-- )catch(
		-- 	print ("newByStruct error")
		-- 	print (structObj as string)
		-- 	print (classof structObj)
		-- 	print (classof structObj == Array)
		-- 	-- print "\n"
		-- )

	),
	fn __add__ key value = (
		if value != undefined do --不要undefined
		(
			--original
			index = finditem this.__keys__ key 
			if index == 0 do(
				append this.__keys__ key
				index = finditem this.__keys__ key
			)
			this.__value__[index] = value
		)
	),

	fn add key value= (
		if superclassof value == StructDef then( --new
			if (this.getClassName value) == "#Struct:MXSJson" then 
			(
				-- print ("add1:"+key)
				this.__add__ key value --original
			)
			else 
			(
				-- print ("add2:"+key)
				mj =MXSJson()
				mj.newByStruct value
				value=mj
				this.add key value --這裏遞歸,可能導致死循環
				-- this.__add__ key value --這裏遞歸,可能導致異常
			)
		)
		else(
			
			if classof value == Array then 
			(
				-- print ("add3:"+key)
				ar=#()
				for i in value do
				(
					-- print ("add array item:"+(i as string))
					mj=MXSJson()
					mj.newByStruct i
					append ar mj
				)
				this.__add__ key ar --original
			)
			else(
				-- print ("add4:"+key)
				this.__add__ key value --original
			)
		)
	)
)

一旦開始寫手就停不下來,程序員啊,大概花了2小時多一些時間。

測試代碼


fn struct2json structObject=(
	print ("struct2json:"+(structObject as string))
	mj = MXSJson()
	mj.__linebreak__="\n" --\n有格式,好看一點,"":沒有格式,字符串就一行
	mj.newByStruct structObject
	js=mj.json()
	print ("json:\n"+js)
)

struct TypeInfo(id,type)
struct PersonInfo(
	name,age,type,
	typeList=#(),
	fn setName =
	(
		this.name=n
		return "abcd"
	)
)
struct BoxInfo(name,count,type)
struct AllInfo(personList,person,box,type)


per=PersonInfo name:"Abc" age:12
per.type=TypeInfo id:0 type:("type0")
-- struct2json per

-- print (per as string)
pList=#()
for i= 1 to 2 do
(
    p=PersonInfo name:"Abc" age:i
    p.type=TypeInfo id:i type:("type"+(i as string))
    append pList p
)
for i= 1 to 2 do 
(
	t=TypeInfo id:i type:("type"+(i as string))
	append per.typeList t
)
-- print (pList as string)

b=BoxInfo name:"box" count:20

all=AllInfo()
all.personList=pList
all.person=per
all.box=b

-- struct2json b
-- struct2json per
-- struct2json pList
struct2json all

結果:

後續實際使用過程中可能還會調整,暫時這樣

-----------------------------------

因爲我只需要3dmax->unity的數據傳導,並不需要考慮讀取json構建struct對象的過程。而從現在查到的來看,好像語法上不支持動態創建struct對象。不過可以考慮用execute "" 構建一個字符串 然後讓它來執行。當前不需要,而且更實際的應該是結合.net json使用吧。

------------------------------------

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章