--tlist = script("3d_import").ReadMAData (member("minido_steps").text) --script("3d_import").buildMayaScene (tlist, member("render")) --script("3d_import").buildMayaScene (tlist, member("render"),#smooth) --build meshes from imported list --pnts (pt) float3 R W A C S -- This attribute is the array of vertex tweaks (relative movements). -- The attribute values are always significant regardless of whether the object has history or not. --vrts (vt) float3 R W A H C S -- This is an internal attribute representing local space vertex position, -- used for file I/O. It should never be directly manipulated by the user. -- If it is modified, the results will be unpredictable. --edge (ed) long3 R W A H C S -- Polygon Edges. -- edg1 (e1) Tint32 0 R W H C -- Polygon first point of edge. -- edg2 (e2) Tint32 0 R W H C -- Polygon second point of edge. -- edgh (eh) Tint32 0 R W H C -- Polygon the hard or smooth information of edge. --normals (n) float3 R W A S -- Special Attribute for file i/o of user specified normals. -- Gets written if there are any user specified normals on the object. -- If the default value which is 1e+20 is written out, -- then it means that system defined normal values are used. -- normalx (nx) float kNormalUndef R W S -- Special Attribute for file i/o of user specified normals - value in x. -- normaly (ny) float kNormalUndef R W S -- Special Attribute for file i/o of user specified normals - value in y. -- normalz (nz) float kNormalUndef R W S -- Special Attribute for file i/o of user specified normals - value in z. --face (fc) polyFaces NULL R W A H C S -- Polygon Faces. on buildMayaScene (me, rMAproplist, r3dMember, rGenerateNormalStyle) nodeCount = rMAproplist.count repeat with n = 1 to nodeCount nodetype = rMAproplist.getpropat(n) nodedata = rMAproplist.getat(n) if nodetype = "transform" then --make model tname = nodedata.getaprop("name") if r3dMember.model(tname) <> 0 then r3dMember.deletemodel(tname) end if tmodel = r3dMember.newmodel(tname) t = nodedata.getaprop("t") if t <> 0 then tmodel.transform.position = t end if r = nodedata.getaprop("t") if r <> 0 then tmodel.transform.rotation = r end if else if nodetype = "mesh" then --textureCoordinateList uvmaps = nodedata.getaprop("uvst") if uvmaps <> 0 then UVlist = uvmaps.getaprop("uvsp") if UVlist <> 0 then uvcount = UVlist.count end if end if --colorlist tcolorlist = [] --** colorcount = 0 --** --vertexList tvertexlist = (nodedata.getaprop("vt")).duplicate()--don't mess with original if tvertexlist <> 0 then vertexcount = tvertexlist.count --tweak pnts ptlist = nodedata.getaprop("pt") if ptlist <> 0 then ptcount = ptlist.count repeat with p = 1 to ptcount pn = ptlist.getpropat(p) vert = tvertexlist.getaprop(pn) + ptlist.getat(p) tvertexlist.setaprop(pn, vert) end repeat end if end if --normallist if voidP(rGenerateNormalStyle) then nVector = vector(1e+020, 1e+020, 1e+020) tempNLIST = nodedata.getaprop("n") if not(VoidP(tempNLIST)) then tnormallist = tempNLIST.duplicate()--don't mess with original** tempNLIST = void else tnormallist = 0 if tnormallist <> 0 then normalcount = tnormallist.count--** else tnormallist = [] tnormallist.add(nVector)--** normalcount = 1 --rGenerateNormalStyle = #smooth end if else normalcount = 0 end if --faces tedgelist = nodedata.getaprop("ed") if tedgelist <> 0 then edgecount = tedgelist.count end if --create face lists tfacelist = nodedata.getaprop("fc") if tfacelist <> 0 then dlist = [1,1,1] faceUVlist = [] faceVTlist = [] faceNMlist = [] vertexNormalList = [:] vertexToEdgeList = [:] vertexToFaceList = [:] nmindex = 0 facecount = tfacelist.count repeat with fc = 1 to facecount fdata = tfacelist[fc] --FACE vertex and normal list FaceEdgeData = fdata.getaprop("f") if FaceEdgeData <> 0 then --edges to.. --face verticies fvertList = [] faceVTlist.add(fvertList) --face normals if normalcount then fnormList = [] faceNMlist.add(fnormList) end if repeat with fv = 1 to 3--f.count --GET EDGE DATA fEdgen = FaceEdgeData[fv] if fEdgeN < 0 then edgeData = tedgelist.getaprop(-fEdgeN -1)-- v1, v2, S/H vt = edgeData[2] + 1 else --fEdgeN >= 0 edgeData = tedgelist.getaprop(fEdgeN)-- v1, v2, S/H vt = edgeData[1] + 1 end if --face vertex fvertList.add(vt) --face vertex normal if normalcount then nm = vertexNormalList.getaprop(vt) if voidP(nm) then nmindex = nmindex + 1 vertexNormalList.addprop(vt, nmindex) fnormList.add(nmindex) else fnormList.add(nm) end if --ref to edges attached to vertex for calcualating default normals edgelist = vertexToEdgeList.getaprop(vt) if voidP(edgelist) then edgelist = [] vertexToEdgeList.addprop(vt, edgelist) end if edgelist.add(fEdgeN) --ref to faces attached to vertex for calcualating default normals facelist = vertexToFaceList.getaprop(vt) if voidP(facelist) then facelist = [] vertexToFaceList.addprop(vt, facelist) end if facelist.add(fc) end if end repeat else faceVTlist.add(dlist) faceNMlist.add(dlist) end if --FACE UV list mu = fdata.getaprop("mu") if mu <> 0 then mu = mu + 1 faceUVlist.add(mu) else faceUVlist.add(dlist) end if end repeat end if -- --calculate normals that are not custom set in Maya (smooth/hard) if normalcount then --nVector = vector(1e+020,1e+020,1e+020) repeat with nm = 1 to normalcount if tnormallist[nm] = nVector then vt = vertexNormalList.getpropat(nm) edgelist = vertexToEdgeList.getaprop(vt) facelist = vertexToFaceList.getaprop(vt) v1 = vector(1,0,0)--**face vetexes v2 = vector(1,0,1) v3 = vector(0,0,1) -- Compute Cross Product to give surface normal tnormallist[nm] = getNormalized(crossProduct(v2-v1,v3-v1)) end if end repeat end if --mesh resource tname = nodedata.getaprop("name") if r3dMember.modelresource(tname) <> 0 then r3dMember.deletemodelresource(tname) end if tResource = r3dMember.newMesh(tname, facecount, vertexcount, normalcount, colorcount, uvcount) if uvcount then tResource.textureCoordinateList = UVlist if colorcount then tResource.colorList = tcolorlist tResource.vertexList = tvertexlist if normalcount then tResource.normallist = tnormallist -- repeat with tface = 1 to facecount if uvcount then tResource.face[tface].textureCoordinates = faceUVlist[tface] --if colorcount then tResource.face[tface].colors = faceColorlist[tface] tResource.face[tface].vertices = faceVTlist[tface] if normalcount then tResource.face[tface].normals = faceNMlist[tface]--** --tResource.face[tface].shader = pTileShaderList[faceSlist[tface]] end repeat --build mesh if voidP(rGenerateNormalStyle) = 0 then tResource.generateNormals(rGenerateNormalStyle) end if tResource.build() --parent model tparent = nodedata.getaprop("parent") if tparent <> 0 then if r3dMember.model(tparent) <> 0 then r3dMember.model(tparent).resource = tResource end if end if end if end repeat end --import Maya ASCII on ReadMAData (me, rMAString) --the floatPrecision = 9 --string chuncks to parse rString = "" --command string nWord = "" --word in line --list to be return createNodeList = [:] --init vars nodeList = 0 --init attribute vars tCommand = 0 tAttribute = 0 attrList = 0 tkeyable = 0 -- tlock = 0 -- tsize = 0 ttype = 0 alteredValue = 0 -- propkey = quote & "." errCount = 0 maxLoops = 65536 --Strip Comments First commentKey = "//" repeat with parseCommandN = 1 to maxLoops Fchar = offset(commentKey, rMAString) if Fchar > 0 then tline = rMAString.char[1..Fchar].line.count endchar = rMAString.line[1..tline].char.count delete rMAString.char[Fchar..endchar] else --exit repeat parseCommandN = maxLoops end if end repeat --Parse repeat with parseCommandN = 1 to maxLoops commandlineend = offset(";", rMAString) if commandlineend then --next command line rString = rMAString.char[1..commandlineend-1] delete rMAString.char[1..commandlineend] --init attribute vars tAttribute = 0 attrList = 0 ParentAttribute = 0 parentlist = 0 tkeyable = 0 -- tlock = 0 -- tsize = 0 ttype = 0 alteredValue = 0 -- r1 = 0 r2 = 0 else --exit return createNodeList end if wCount = rString.word.count repeat with tword = 1 to wCount nWord = rString.word[tword] --skip commented lines --if nWord.char[1..2] = "//" then exit repeat --parse text case nWord of "requires": tCommand = nWord --file requirements --put rString exit repeat --next line "currentUnit": tCommand = nWord --put rString --** set up unit conversion if not inches exit repeat --next line "createNode": tCommand = nWord nodeList = [:]--nodeData tword = tword + 1 createNodeList.addprop(rString.word[tword], nodeList) "-n","-name": --name tword = tword + 1 tname = value ( rString.word[tword] ) nodeList.setaprop("name", tname) "-p","-parent": --parent tword = tword + 1 tparent = value ( rString.word[tword] ) nodeList.setaprop("parent", tparent) "setAttr": tCommand = nWord tAttribute = 1--find attibute to set --Sets the value of a dependancy node attribute. --No value for the the attribute is needed when the -l/-k/-s flags are used. --The -type flag is only required when setting a non-numeric attribute. "-k","-keyable": --boolean --Sets the attribute's keyable state on or off. tword = tword + 1 tkeyable = rString.word[tword] = "on" "-l","-lock": -- boolean --Sets the attribute's lock state on or off. tword = tword + 1 tlock = value ( rString.word[tword] ) "-s","-size","-shared": --int --** if tCommand = "setAttr" then --** -- "-size" Defines the size of a multi-attribute array. This is only a hint, used to help allocate memory as efficiently as possible. tword = tword + 1 tsize = value ( rString.word[tword] ) else if tCommand = "createNode" then--** createNode -- "-shared" This node is shared across multiple files, so only create it if it does not already exist. nodeList.setaprop("shared", 1) else put "Unexpected Flag" && tword && tCommand end if "-typ","-type": --string --Identifies the type of data. If the -type flag is not present, a numeric type is assumed. tword = tword + 1 ttype = value ( rString.word[tword] ) case ttype of "short2","long2": --2 integers "short3","long3": --3 integers "int32Array","doubleArray": --list integers or floats "float2","double2": --2 floats if tsize = 0 then tword = tword + 2 --*nodeList nodeList.setaprop(tAttribute, [value(rString.word[tword-1]),value(rString.word[tword])]) else -- ** do list --*AttrList repeat with arrayindex = 1 to tsize tword = tword + 2 AttrList.addprop(r1 + arrayindex-1,[value(rString.word[tword-1]),value(rString.word[tword])]) end repeat end if "float3","double3": --3 floats --(vector) if tsize = 0 then tword = tword + 3 --*nodeList nodeList.setaprop(tAttribute, vector(value(rString.word[tword-2]),value(rString.word[tword-1]),value(rString.word[tword]))) else -- ** do list --*AttrList repeat with arrayindex = 1 to tsize tword = tword + 3 AttrList.addprop(r1 + arrayindex-1, vector(value(rString.word[tword-2]),value(rString.word[tword-1]),value(rString.word[tword]))) end repeat end if "matrix": "pointArray": --list points "vectorArray": --list vectors "string":---------------------------- --string tstring = value ( rString.word[tword + 1..wCount] ) tword = wCount if stringP(tstring) = 0 then tstring = "" put "could not parse string" && rString errCount = errCount + 1 end if if tAttribute <> 1 and tAttribute <> 0 then if tsize = 0 then nodeList.setaprop(tAttribute, tstring) --*nodeList else AttrList.setaprop(tAttribute, tstring) --*AttrList--tsize end if else put "attribute not found for string" && tstring errCount = errCount + 1 end if ----------------------------------- "stringArray": --list strings "polyFace","polyFaces": --// "f" specifies the ids of the edges making up a face - --// negative value if the edge is reversed in the face --// "h" specifies the ids of the edges making up a hole - --// negative value if the edge is reversed in the face --// "mf" specifies the ids of texture coordinates (uvs) for a face. --// This data type is obsolete as of version 3.0. It is replaced by "mu". --// "mh" specifies the ids of texture coordinates (uvs) for a hole --// This data type is obsolete as of version 3.0. It is replaced by "mu". --// "mu" The first argument refers to the uv set. This is a zero-based --// integer number. The second argument refers to the number of vertices (n) --// on the face which have valid uv values. The last n values are the uv --// ids of the texture coordinates (uvs) for the face. These indices --// are what used to be represented by the "mf" and "mh" specification. --// There may be more than one "mu" specification, one for each unique uv set. --// "fc" specifies the color index values for a face if tsize = 0 then put "No size set for" && ttype && "//" && rString tsize = 1 AttrList = nodeList.getaprop(tAttribute) if AttrList = 0 then AttrList = [:] nodeList.setaprop(tAttribute, AttrList) end if end if nslist = "" remainingwords = rString.word[tword+1..rString.word.count] LinesInVal = remainingwords.line.count / tsize repeat with faceindex = 1 to tsize repeat with arrayindex = 1 to LinesInVal currline = remainingwords.line[(faceindex-1) * LinesInVal + arrayindex] subattribute = currline.word[1] subAttrList = AttrList.getaprop(r1 + faceindex-1) if subAttrList = 0 then subAttrList = [:] AttrList.addprop(r1 + faceindex-1, subAttrList) end if case subattribute of "f": edgecount = value(currline.word[2]) if edgecount > 3 then put "Meshes must be traingulated" tval = [] repeat with tedge = 1 to edgecount tval.add(value(currline.word[2 + tedge])) end repeat "mu": mapref = value(currline.word[2]) if mapref > 0 then put "Multiple shaders not supported" tval = [] vertcount = value(currline.word[3]) repeat with tvert = 1 to vertcount tval.add(value(currline.word[3 + tvert])) end repeat otherwise --list errors if offset( subattribute, nslist ) = 0 then nslist = nslist && subattribute end if --add default tval = currline.word[1..currline.word.count] end case subAttrList.setaprop(subattribute, tval) end repeat end repeat --report errors if nslist.length > 0 then put "Face attributes not yet supported:" && nslist end if "mesh": --// "v" specifies the vertices of the polygonal mesh --// "vn" specifies the normal of each vertex --// "vt" is optional and specifies a U,V texture coordinate for each vertex --// "e" specifies the edge connectivity information between vertices "cone","reflectanceRGB","spectrumRGB","componentList","attributeAlias","nurbsCurve","nurbsSurface","nurbsTrimface","lattice": --Not Supported end case --next command tword = wCount "-av","-alteredValue": --The value is only the current value, which may change in the next evalution (if the attribute has an incoming connection). This flag is only used during file I/O, so that attributes with incoming connections do not have their data overwritten during the first evaluation after a file is opened. otherwise --value (not a command or flag) if tAttribute = 1 then --looking for Attr to set if nWord.char[1..2] = propkey then attibuteDef = nWord.char[3..nWord.char.count-1] --check for array and child prop []. arrayCharN = offset("]", attibuteDef) if arrayCharN = 0 then --not list tAttribute = attibuteDef if tsize = 0 then nodeList.setaprop(tAttribute, void) --*nodeList else AttrList = nodeList.getaprop(tAttribute) if AttrList = 0 then AttrList = [:] nodeList.setaprop(tAttribute, attrList) --*nodeList --*AttrList end if end if else --list--------------------- arraySN = offset("[", attibuteDef) --get range rangestring = attibuteDef.char[arraySN+1..arrayCharN-1] r1 = value (rangestring) endrangeS = offset(":", rangestring) if endrangeS > 0 then r2 = rangestring.char[endrangeS+1..rangestring.char.count] else r2 = r1 end if --size if tsize = 0 then --put "Array size not defined" && attibuteDef tsize = (r2 - r1) + 1 end if --check for sub list if arrayCharN = attibuteDef.char.count then --no child prop tAttribute = attibuteDef.char[1..arraySN-1] --init array AttrList = nodeList.getaprop(tAttribute) if AttrList = 0 then AttrList = [:] nodeList.setaprop(tAttribute, attrList) --*nodeList else --array with sub prop --------------------- --set parent ParentAttribute = attibuteDef.char[1..arraySN-1] parentlist = nodeList.getaprop(ParentAttribute) if parentlist = 0 then parentlist = [:] nodeList.setaprop(ParentAttribute, parentlist) --*nodeList --*AttrList end if tAttribute = attibuteDef.char[arrayCharN+2..nWord.char.count] --------------------- arrayCharN = offset("]", tAttribute) if arrayCharN = 0 then --sub is not list parentlist.setaprop(tAttribute, 0) attrList = parentlist else --sub is list if arrayCharN = tAttribute.char.count then --no child prop arraySN = offset("[", tAttribute) tAttribute = tAttribute.char[1..arraySN-1] --init array AttrList = nodeList.getaprop(tAttribute) if AttrList = 0 then AttrList = [:] parentlist.setaprop(tAttribute, AttrList) else --too many child props put "more than one nested attribute not supported" && tAttribute end if end if --------------------- end if end if else --no prop, command or flag count put "Unexpected String while setting attribute:" && nWord && "//" && rString errCount = errCount + 1 end if else if tAttribute <> 0 then --attribute value case nWord of "yes", "on", "true": tval = 1 "no", "off", "false": tval = 0 otherwise tval = value (nWord) if voidP(tval) then put "Unexpected:" && tAttribute && nWord && "//" && rString --** tval = nWord end if end case if tsize = 0 then nodeList.setaprop(tAttribute, tval) --*nodeList --*AttrList else -- ** do list --*AttrList remainingwords = rString.word[tword..rString.word.count] WordsInVal = remainingwords.word.count / tsize case tAttribute of "vt": repeat with arrayindex = 1 to tsize startwordn = (arrayindex-1) * WordsInVal + 1 -- tval = vector(value(remainingwords.word[startwordn]), value(remainingwords.word[startwordn+1]), value(remainingwords.word[startwordn+2])) -- AttrList.addprop(r1 + arrayindex-1, tval) end repeat "ed": repeat with arrayindex = 1 to tsize startwordn = (arrayindex-1) * WordsInVal + 1 -- tval = [value(remainingwords.word[startwordn]), value(remainingwords.word[startwordn+1]), value(remainingwords.word[startwordn+2])] -- AttrList.addprop(r1 + arrayindex-1, tval) end repeat otherwise put "Uknown Attribute Type" && tAttribute && "//" && rString repeat with arrayindex = 1 to tsize startwordn = (arrayindex-1) * WordsInVal + 1 -- tval = remainingwords.word[startwordn..startwordn + WordsInVal-1] -- AttrList.addprop(r1 + arrayindex-1, tval) end repeat end case tsize = 0 end if --next command tword = wCount else --no prop, command or flag count put "Unexpected String while Parsing:" nWord && "//" && rString errCount = errCount + 1 exit repeat end if end case if errCount > 10 then put "Too many errors" return createNodeList end if end repeat end repeat return createNodeList end