-- UniRemover.ms -- By Nikolay Litvinov (gniklit@gmail.com) -- Created On: 2013-11-02 -- Modified: 2016-04-05 -- tested using Max 2016 messageBox "Category: \"Niklit Scripts\"" macroScript uniremover Category:"Niklit Scripts" Tooltip:"UniRemover" ( ------------------------FUNCTIONS------------------------------ gco = modPanel.getCurrentObject() universal=null global s1 if selection.count == 1 do s1=selection[1] Verts_not2e=#{} Verts_2e=#{} struct polyFns ( fn RemoveVertex fco=fco.Remove selLevel:#Vertex, fn RemoveEdge fco=fco.Remove selLevel:#Edge, fn DeSelectionVert node_i fco=fco.SetSelection #Vertex #{}, fn SetSelectionVert node_i fco Verts=fco.SetSelection #Vertex Verts, fn GetSelectionEdge fco node_i =fco.getselection #edge, fn RemoveIsoVerts fco = fco.deleteIsoVerts(), fn GetEdgeVertex fco EAr v node_i = fco.GetEdgeVertex EAr v, fn GetVertexEdgeCount fco VAr node_i = fco.GetVertexEdgeCount VAr ) struct polyMODFns ( fn RemoveVertex fco=fco.buttonop #RemoveVertex, fn RemoveEdge fco=fco.buttonop #RemoveEdge, fn DeSelectionVert node_i fco=setVertSelection node_i fco #{} keep:off, fn SetSelectionVert node_i fco Verts=(setVertSelection node_i fco #{} keep:off; setVertSelection node_i fco Verts keep:on), fn GetSelectionEdge fco node_i=fco.getselection #edge node: node_i, fn RemoveIsoVerts fco = fco.ButtonOp #RemoveIsoVerts, fn GetEdgeVertex fco EAr v node_i = fco.GetEdgeVertex EAr v node: node_i, fn GetVertexEdgeCount fco VAr node_i = fco.GetVertexEdgeCount VAr node: node_i ) fn tryInit fco = case classOf fco of ( Editable_Poly: (universal = polyFns(); "Editable_Poly") Edit_Poly: (universal = polyMODFns(); "Edit_Poly") --default: (messageBox "This script only works with Edit/Editable_Poly objects."; false) ) fn sendkeys_CtrlRemove_fn=( vbs_Fpath = (GetDir #scripts) + "\\sendkeys.vbs" if not doesFileExist vbs_Fpath then ( f = createFile vbs_Fpath format "'***************************************\n' wscript shell sendkeys\n' send.vbs\n'***************************************\nOption Explicit\nDim WshShell\nSet WshShell = WScript.CreateObject(\"WScript.Shell\")\nWshShell.SendKeys(\"^{BS}\")" to:f close f shellLaunch "explorer.exe" vbs_Fpath) else shellLaunch "explorer.exe" vbs_Fpath ) fn CtrlRemove_fn=( --for i in desktopChildren do format "%\n" i max_hwnd=for i in (windows.getChildrenHWND (windows.getDesktopHWND())) where (i[4] == "3DSMAX") do (exit with i[1]) WM_ACTIVATE = 0x6 Windows.sendMessage max_hwnd WM_ACTIVATE max_hwnd 0 sendkeys_CtrlRemove_fn() ) fn RemoveEdge_fn fco =( EdgeAr=for i in selection collect (universal.GetSelectionEdge fco i) as array VertAr=#() for i=1 to EdgeAr.count do ( append VertAr #() for e=1 to EdgeAr[i].count do for v=1 to 2 do append VertAr[i] (universal.GetEdgeVertex fco EdgeAr[i][e] v selection[i]) ) for i=VertAr.count to 1 by-1 do (universal.SetSelectionVert selection[i] fco ((VertAr[i])as BitArray)) universal.RemoveEdge fco VertAr=for i=1 to selection.count collect (getVertSelection selection[i].mesh) as array set_Vert= for i=1 to VertAr.count collect ( for v=1 to VertAr[i].count where (universal.GetVertexEdgeCount fco VertAr[i][v] selection[i]) < 3 and VertAr[i][v]<=numPoints selection[i] collect VertAr[i][v] )as BitArray for i=set_Vert.count to 1 by-1 do (universal.SetSelectionVert selection[i] fco set_Vert[i]) universal.RemoveVertex fco ) fn RemoveVertex_fn fco=( check_VuE=#(fco.ConvertSelectionToBorder #Vertex #Edge, try (getEdgeSelection $).numberset catch()) if check_VuE[2]==undefined do check_VuE[2]=0 if check_VuE[1]==0 and check_VuE[2]==0 then universal.RemoveVertex fco; else RemoveEdge_fn fco) fn NumV_fn fco = fco.GetNumVertices() fn PushPrVertSel_fn fco =(PushPrompt ((((fco.getSelection #Vertex).numberset) as String) + " Vertex selected")) fn Verts_2E_fn fco = ( arV=(getVertSelection selection[1].mesh) if arV.numberset==0 do for i=1 to selection.count do ( allVerts=#{1..selection[1].numverts} Verts_2e = (for v in allVerts where (universal.GetVertexEdgeCount fco v selection[1])==2 collect v) as BitArray OpenE=#() openEdges.Check currentTime selection[1] &OpenE OpenVert=(for e in OpenE collect universal.GetEdgeVertex fco e 1 selection[1]) as BitArray if OpenVert.numberset==0 then universal.SetSelectionVert selection[1] fco Verts_2e else ( FiltOpenV = Verts_2e-OpenVert universal.SetSelectionVert selection[1] fco FiltOpenV ) ) ) fn epSO_1_fn fco = (V_state1=NumV_fn fco VertAr=for i in selection collect (getVertSelection i.mesh) as Array for i=1 to VertAr.count do if VertAr[i].count==0 then (universal.RemoveIsoVerts fco Verts_2E_fn fco PushPrVertSel_fn fco) else RemoveVertex_fn fco max select V_state2=NumV_fn fco differV=V_state1-V_state2 if differV > 0 do PushPrompt (differV as string + " Vertex removed") ) fn epSO_2_fn fco =( try for i in selection do (setVertSelection i fco #{} keep:off) catch() Es=fco.getselection #Edge; V_state1=NumV_fn fco if Es.count==Es.numberset then PolyToolsModeling.Quadrify off off else sendkeys_CtrlRemove_fn() --CtrlRemove_fn() max select V_state2=NumV_fn fco differV=V_state1-V_state2 if differV > 0 do PushPrompt (differV as string + " Vertex removed") ) fn isEmpty_KNspl_fn=( numspl=(for i=1 to numSplines $ collect i).count isEmpty_kn=(for i=1 to numspl where ((getKnotSelection $ i)as BitArray).isEmpty collect on).count isEmpty_kn==numspl) fn DOTselKnots_fn= ( if subobjectlevel!=1 do subobjectlevel=1 global DOTknotSel_fn, getKnotSelection_ar, numSplines_ar numSplines_ar=for i=1 to numSplines $ collect i fn getKnotSelection_ar_fn=(getKnotSelection_ar=for i=1 to numSplines_ar.count collect (getKnotSelection $ i)as BitArray) getKnotSelection_ar_fn() isEmptyKnots=for i=1 to getKnotSelection_ar.count where not getKnotSelection_ar[i].isEmpty collect i fn DOTknotSel_fn=( DOTselKnots= ( for spl=1 to numSplines_ar.count collect (for i=numKnots $ spl to 1 by -2 collect i) as BitArray ) setKnotSelection_ar=for i=1 to numSplines_ar.count collect (getKnotSelection_ar[i]*DOTselKnots[i]) as Array for i=1 to numSplines_ar.count do setKnotSelection $ numSplines_ar[i] setKnotSelection_ar[i] keep: off ) if isEmptyKnots[1]==undefined then (max select all;getKnotSelection_ar_fn();DOTknotSel_fn()) else DOTknotSel_fn() ) fn RemSpl_fn fco = ( if classof fco != Edit_Spline then fco = $ if (subobjectLevel<3 and subobjectLevel != 0) then actionMan.executeAction 0 "40020"/*Delete Objects*/ else splineOps.startTrim fco ) fn ScaleNegativeFixer_fn fco =( ResetXForm fco AddModifier fco (Normalmodifier ()) fco.modifiers[#Normal].flip = on collapseStack fco ) fn SetVertOpen_2e_fn fco =( OpenE=#() openEdges.Check currentTime selection[1] &OpenE allOpnVert=for e in OpenE collect fco.GetEdgeVertex e 1 Verts_2e = (for v in allOpnVert where fco.GetVertexEdgeCount v == 2 collect v) as BitArray subObjectLevel=1 universal.SetSelectionVert selection[1] fco Verts_2e ) fn xFixShapeX_fn fco = (fco.pivot=fco.center rotate fco (angleaxis 270 [0,1,0]) ResetXForm fco; collapseStack fco rotate fco (angleaxis -270 [0,1,0]) ) fn yFixShapeX_fn fco = (fco.pivot=fco.center rotate fco (angleaxis 270 [1,0,0]) ResetXForm fco; collapseStack fco rotate fco (angleaxis -270 [1,0,0]) ) fn zFixShapeX_fn fco = (fco.pivot=fco.center ResetXForm fco; collapseStack fco ) fn fixShapeXform_fn fco = ( with redraw off ( BBo=nodeGetBoundingBox fco (matrix3 1) xBB=BBo[2].x-BBo[1].x yBB=BBo[2].y-BBo[1].y zBB=BBo[2].z-BBo[1].z xOrder=(xBB0 then ( global E0=fco.getselection #Edge fco.ConvertSelection #Face #Edge global stateSm case stateSm of ( undefined: (fco.autoSmoothThreshold = 180; fco.ButtonOp #Autosmooth; stateSm=true) true: (fco.ButtonOp #MakeSmoothEdges; stateSm=undefined) ) try $.selectedEdges=E0 catch (setEdgeSelection s1 fco #{} keep:off; setEdgeSelection s1 fco E0 keep:on) ) else fco.SmGrpFloater() max select ) ---------------------------SCRIPT----------------------------------- for obj in selection do ( if superclassof obj==GeometryClass and (subObjectLevel==0 or subObjectLevel==undefined) do ( if classof obj!=Editable_Poly do ( global noRes=true; converttopoly obj; max modify mode) if obj.scale==[-1,-1,-1] do (ScaleNegativeFixer_fn obj; messagebox "Fixed scale [-1,-1,-1]"; noRes=true) ) --if sDM=(obj.modifiers.count>0 and (subObjectLevel==0 or subObjectLevel==undefined) and (classof obj!=Edit_Poly and classof obj!=Edit_Spline)) do deleteModBtnPress_fn() if (classOf obj != Line and classOf obj != SplineShape and obj.category == #Splines) do (convertToSplineShape obj; noRes=true) ) noRes=false if (subObjectLevel==0 or subObjectLevel==undefined) and selection.count>0 and noRes==false do ( suspendediting() sel0=getCurrentSelection() arO=for i in sel0 where superclassof i==GeometryClass collect i for i in arO do i.material=undefined arShO=for i in sel0 where superclassof i==shape collect i arPivot0=for i in arO collect i.pivot arlayer0=for i in arO collect i.layer arFixO=for i in arO collect convertToPoly (editable_mesh name: i.name) --for i=1 to arFixO.count do attach arFixO[i] arO[i] --attach mesh for i=1 to arFixO.count do polyop.attach arFixO[i] arO[i] for i in arFixO do converttoPoly i for i=1 to arFixO.count do arFixO[i].pivot=arPivot0[i] for i=1 to arFixO.count do arlayer0[i].addnode arFixO[i] try (for i in arShO do fixShapeXform_fn i) catch() join arFixO arShO select arFixO resumeediting() max select ) if selection.count==0 do select (maxOps.getNodeByHandle (amax (for o in objects collect o.inode.handle))) case classOf gco of ( Editable_poly: ( tryInit gco case subobjectLevel of ( 1: epSO_1_fn gco 2: epSO_2_fn gco 3: (SetVertOpen_2e_fn gco; PushPrVertSel_fn gco) 4: SO4_op_fn gco 5: (gco.SmGrpFloater(); max select) ) ) Edit_Poly: ( tryInit gco case subobjectLevel of ( 1: epSO_1_fn gco 2: epSO_2_fn gco 3: (gco.SetSelection #Vertex #{} SetVertOpen_2e_fn gco; PushPrVertSel_fn gco) 4: SO4_op_fn gco 5: (gco.SmGrpFloater(); max select) ) ) Line: if isEmpty_KNspl_fn() and subobjectlevel==1 then DOTselKnots_fn() else (V_state1 = numKnots $; RemSpl_fn gco; max select; V_state2=numKnots $; differV=V_state1-V_state2 if differV > 0 do PushPrompt (differV as string + " Knots removed")) SplineShape: if isEmpty_KNspl_fn() and subobjectlevel==1 then DOTselKnots_fn() else (V_state1 = numKnots $; RemSpl_fn gco; max select; V_state2=numKnots $; differV=V_state1-V_state2 if differV > 0 do PushPrompt (differV as string + " Knots removed")) Edit_Spline: (RemSpl_fn gco; max select) ) )