MAXScript学习笔记(3) 功能:分离元素 您所在的位置:网站首页 3dmax分离面 MAXScript学习笔记(3) 功能:分离元素

MAXScript学习笔记(3) 功能:分离元素

2024-06-02 03:29| 来源: 网络整理| 查看: 265

一.分离一个特定元素(Detach Element)

要对一组相同的物体(Editable_Poly)进行分离物体里面某一个部分的功能。

本来以为Editable_Poly里面会有相关的Element的API,结果全是点(Vert)线(Edge)面(Face),只有一个getElementsUsingFace

而它的参数是 faceList,问题是在polyop里我还找不到getFace的函数....

也就是说这个界面上的基本操作实际上是封装了一层的,api层至多到Face层级,没有更高的层级了。

搜索了一番,找到了两个有用的函数

fn getElements obj= ( try ( f=obj.numfaces eles=#() done=#() for i=1 to f do ( if (finditem done i)==0 then ( case (classof obj) of ( editable_mesh:(faces=(meshop.getElementsUsingFace obj #(i)) as array) editable_poly:(faces=(polyop.getElementsUsingFace obj #(i)) as array) ) append eles faces join done faces ) ) ) catch( eles=undefined ) return eles )

参考:https://www.maxforums.org/forum/thread/maxscript_mesh_elements/1

function detachElements nin_Object = ( naOut = #() if classof nin_Object == Editable_Poly do ( suspendediting() try ( undo off ( with redraw off ( while polyOp.getNumFaces nin_Object != 0 do ( elementSel = (polyOp.getElementsUsingFace nin_Object #{1}) baseName = nin_Object.name newName = (uniqueName baseName) polyOp.detachFaces nin_Object elementSel asNode:true name:newName detachedObj = (getNodeByName newName) append naOut detachedObj ) for o in naOut do ( baseName = (substring o.name 1 (o.name.count-3)) uniquePart = (substring o.name (o.name.count-2) o.name.count) finalName = (baseName + "_" + uniquePart) o.name = finalName centerPivot o ) ) ) ) catch(messageBox "error: detach objects") resumeediting() delete nin_Object ) naOut as array )

参考:http://www.scriptspot.com/forums/3ds-max/general-scripting/edit-poly-modifier-quick-detach

接下来又是二次开发的工作了,我要把Element相关的操作封装到一个ElementOp里面

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

二、按材质分离元素

本来以为是分离就好了,结果还要合并相同材质的物体

结果1:将窗户的玻璃和外框分离,并放在一个组里,每个窗户变成一个组,里面有两个子物体

结果2:在上面的基础上,将全部的玻璃合并在一个物体里,外框合并在一个物体里

整个过程学到了Element操作,材质操作,分离合并,从门外汉入门了一些。

把整个ms贴出来吧,使用的是最下面的函数。

print "-------------------------- ElementOp.ms ---------------------------------" struct ElementOpClass ( fn GetElements obj= ( print ("->ElementOp.GetElements():"+(obj as string)) try ( f=obj.numfaces eles=#() done=#() for i=1 to f do ( if (finditem done i)==0 then ( case (classof obj) of ( editable_mesh:(faces=(meshop.GetElementsUsingFace obj #(i)) as array) editable_poly:(faces=(polyop.GetElementsUsingFace obj #(i)) as array) ) append eles faces join done faces ) ) ) catch( eles=undefined ) return eles ), fn DetachElement obj ele= ( newName = (uniqueName obj.name) polyOp.detachFaces obj ele asNode:true name:newName detachedObj = (getNodeByName newName) centerPivot detachedObj --没有这句话的话,新的物体的轴心还是在原来的物体的轴心的位置 return detachedObj ), fn RenameElement o = -- ( baseName = (substring o.name 1 (o.name.count-3)) uniquePart = (substring o.name (o.name.count-2) o.name.count) finalName = (baseName + "_" + uniquePart) o.name = finalName ), fn RenameElements objs = -- ( if objs == undefined do ( print "RenameElements objs == undefined" return undefined ) for o in objs do ( RenameElement o ) ), --ElementOp.DetachAllElements $ fn DetachAllElements obj = ( print ("->ElementOp.DetachAllElements():"+(obj as string)) naOut = #() if classof obj != Editable_Poly do convertToPoly obj if classof obj == Editable_Poly do ( -- suspendediting() -- try -- ( -- undo off ( with redraw off ( while polyOp.getNumFaces obj != 0 do ( elementSel = (polyOp.GetElementsUsingFace obj #{1}) detachedObj=DetachElement obj elementSel append naOut detachedObj ) for o in naOut do ( RenameElement o ) ) ) -- ) -- catch(messageBox "error: detach objects") -- resumeediting() delete obj ) naOut as array ), fn DetachElements_Inner obj indexes isCombine:true isGroup:true=( print ("->Elements.DetachElements():"+(obj as string)) if classof obj != Editable_Poly do ( convertToPoly obj ) local eleList=GetElements obj print eleList local newObjs=#(obj) if isCombine then ( local newEle=#() if indexes!= undefined do ( for i in indexes do ( ele=eleList[i] print (ele as string) join newEle ele ) local detachedObj=DetachElement obj newEle append newObjs detachedObj ) ) else ( if indexes!= undefined do ( for i in indexes do ( local detachedObj=DetachElement obj eleList[i] append newObjs detachedObj ) ) ) local oriName=obj.name obj.name=obj.name+"000" --保持命名一致 for o in newObjs do ( RenameElement o ) if isGroup then ( g1=group newObjs name:oriName setGroupOpen g1 true return g1 ) return newObjs ), --ElementOp.DetachElements $ #(1,2,3) --ElementOp.DetachElements $ #(1,2,3) isCombine:false --ElementOp.DetachElements $ #(1,2,3) isGroup:false --ElementOp.DetachElements $ #(1,2,3) isGroup:false isAttachAll:true fn DetachElements objList indexes isCombine:true isGroup:true isAttachAll:false= ( if objList == undefined do ( print "DetachElements objList == undefined" return undefined ) newObjList=#() for obj in objList do ( print ("->Elements.DetachElements():"+(obj as string)) newObj=DetachElements_Inner obj indexes isCombine:isCombine isGroup:isGroup append newObjList newObj --exit ) if newObjList.count > 1 and isCombine == true and isGroup==false and isAttachAll == true do ( print "attachAll" ) print (newObjList as string) ), --ElementOp.DetachByMaterial $ fn DetachByMaterial_Inner obj isGroup:true= ( if obj == undefined do (return undefined) if classof obj != Editable_Poly do ( convertToPoly obj ) oldName=obj.name m=obj.material if classof m == MultiMaterial do ( newObjs=#() for i=1 to m.numsubs do ( mId=m.MaterialIDList[i] obj.selectByMaterial mId m_faces = getFaceSelection obj detachedObj=DetachElement obj m_faces subM=m.MaterialList[i] detachedObj.material=subM print ("detachedObj Material"+(subM as string )) append newObjs detachedObj ) RenameElements newObjs delete obj if isGroup do ( g=group newObjs name:oldName setGroupOpen g true return g ) return newObjs ) return undefined ), fn FindObjectsByMaterial objList m = ( items=#() for obj in objList do ( if isDeleted obj do continue if obj.material == m do append items obj ) return items ), --ElementOp.AttachObjects $ fn AttachObjects objList = ( print objList if objList == undefined do ( print "AttachObjects objList == undefined" return undefined ) if classof objList != Array and classof objList !=ObjectSet do ( format "skip classof:%\n" (classof objList) return objList ) if objList.count < 2 do return objList objList=objList as Array --记得要转换 不然会出错 first = objList[1] format "first:%\n" first format "objList1:%\n" objList.count -- deleteItem objList first -- while objList.count > 0 for i =2 to objList.count do ( obj = objList[i] format "obj:%\n" obj if obj == undefined do continue polyop.attach first obj --ObjectSet的情况下,会自动把删除的模型去掉 i-=1 format "count:%\n" objList.count ) format "objList:%\n" objList CenterPivot first ), fn CollectMaterials objList= ( mList=#() for obj in objList do ( m=obj.material i = findItem mList m if i == 0 do append mList m ) format "materialList:%\n" mList return mList ), --ElementOp.AttachByMaterial $ fn AttachByMaterial objList= ( if objList == undefined do ( print "AttachByMaterial objList == undefined" return undefined ) newObjList=#() mList=CollectMaterials objList for m in mList do ( subList=FindObjectsByMaterial objList m format "subList:%\n" subList newObj=AttachObjects subList -- append newObjList newObj ) return newObjList ), --ElementOp.DetachByMaterial $ --ElementOp.DetachByMaterial $ isGroup:false --ElementOp.DetachByMaterial $ isCombineByMat:true fn DetachByMaterial objList isGroup:true isCombineByMat:false= ( if objList == undefined do ( print "DetachElements objList == undefined" return undefined ) if isCombineByMat do isGroup=false newObjList=#() objList=objList as Array --记得要转换 不然会出错 for obj in objList do ( print ("->Elements.DetachElements():"+(obj as string)) newObj=DetachByMaterial_Inner obj isGroup:isGroup join newObjList newObj --exit ) print (newObjList as string) if newObjList.count > 1 and isCombineByMat ==true and isGroup == false do ( print "attachAll" newObjList=AttachByMaterial newObjList print (newObjList as string) ) ) ) ElementOp=ElementOpClass()

大小写上,我自己的约定是 struct和function是大写开头的,虽然写着写着有时候自己也写成了小写,后面会再替换一下,javascript和java的函数名都是小写开头的,c#的是大写开头的,但是这些语言有()作为函数的调用,这里没有,还是区分一些 不然两个并列的字符串 感觉像是两个变量一样。

命名上函数名都是动词+名词,变量名都是名称。

实际使用环境中,这些窗户是分别在不同楼层中的,要按楼层分别处理。

然后还有楼梯、栏杆的分离合并操作。

另外就是一般的代码操作都能回退,这些操作完后如果回退,可能会导致3dmax崩溃,这我就不研究了,使用前备份一下文件就行。

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有