-- UniRemover.ms -- By Nikolay Litvinov (gniklit@gmail.com) -- Created On: 2013-11-02 -- Modified: 2017-10-07 -- tested using Max 2016 -- Thanx Gene Crucean for fun fuction Quadriangulate -- v.9.52 Решён конфликт операций конвертации примитивов в Editable_poly messageBox "Category: \"Niklit Scripts\"" macroScript uniremover Category:"Niklit Scripts" Tooltip:"UniRemover" ( ------------------------FUNCTIONS------------------------------ polyO=null global directRotation_forfix Verts_not2e=#{} Verts_2e=#{} struct polyFns ( fn SetSelectionVert node_i fco Verts=fco.SetSelection #Vertex Verts, 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 SetSelectionVert node_i fco Verts=(setVertSelection node_i fco #{} keep:off; setVertSelection node_i fco Verts keep:on), 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: (polyO = polyFns(); "Editable_Poly") Edit_Poly: (polyO = polyMODFns(); "Edit_Poly") --default: (messageBox "This script only works with Edit/Editable_Poly objects."; false) ) fn sendkeys_CtrlRemove_fn =( ctrlBS_vbs=(pathConfig.GetDir #scripts) +"\\ctrl+BS.vbs" if (getFiles ctrlBS_vbs).count==0 do ( f=createFile ctrlBS_vbs format ("set s = CreateObject(\"WScript.Shell\")\ns.SendKeys(\"^{BS}\")") to:f close f ) --vbsPath = (GetDir #scripts) + "\\ctrl+BS.vbs" shellLaunch "explorer.exe" ctrlBS_vbs ) fn Quadriangulate_fn=( disablesceneredraw() tb = Bomb strength:0 gravity:0 detonation:0f minFragmentSize:2 maxFragmentSize:2 falloff:100 pos:[0,0,0] name:"tempbomb" try ( if classOf selection[1]!= Editable_Poly do convertToPoly selection[1] oldname = selection[1].name oldpivot = selection[1].pivot selection[1].name = "deleteoldmesh" bindSpaceWarp selection[1] $tempbomb snapshot selection[1] name:"tempmesh" select $tempmesh macros.run "Modifier Stack" "Convert_to_Poly" subobjectLevel = 2 actionMan.executeAction 0 "40021" $.EditablePoly.Remove () $.edgeWeldThreshold = 0.00001 $.EditablePoly.weldFlaggedEdges () subobjectLevel = 0 $.pivot=oldpivot $tempmesh.name=oldname ) catch() delete $deleteoldmesh* delete $tempbomb clearSelection() enablesceneredraw() redrawviews() ) 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 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 polyO.SetSelectionVert selection[1] fco Verts_2e ) fn xFixShapeX_fn fco = (fco.pivot=fco.center case directRotation_forfix of ( undefined: (rotate fco (angleaxis 270 [0,1,0]); ResetXForm fco; collapseStack fco; rotate fco (angleaxis -270 [0,1,0]); directRotation_forfix=true) true: (rotate fco (angleaxis 90 [0,1,0]); ResetXForm fco; collapseStack fco; rotate fco (angleaxis -90 [0,1,0]); directRotation_forfix=undefined) ) ) fn yFixShapeX_fn fco = (fco.pivot=fco.center case directRotation_forfix of ( undefined: (rotate fco (angleaxis 270 [1,0,0]); ResetXForm fco; collapseStack fco; rotate fco (angleaxis -270 [1,0,0]); directRotation_forfix=true) true: (rotate fco (angleaxis 90 [1,0,0]); ResetXForm fco; collapseStack fco; rotate fco (angleaxis -90 [1,0,0]); directRotation_forfix=undefined) ) ) fn zFixShapeX_fn fco = (fco.pivot=fco.center case directRotation_forfix of ( undefined: (ResetXForm fco; collapseStack fco; directRotation_forfix=true) true: (rotate fco (angleaxis 180 [1,0,0]); ResetXForm fco; collapseStack fco; rotate fco (angleaxis -180 [1,0,0]); directRotation_forfix=undefined) ) ) 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=(xBB 0 do PushPrompt (differV as string + " Vertex removed") ) global edgesel fn MidChamfer_fn= ( with undo off $.GrowSelection () edgGrow=polyop.getEdgeSelection $ edg_ext=edgGrow-edgesel $.setselection #edge edg_ext $.connectEdgeSegments = 2 $.connectEdgeSlide = 0 $.EditablePoly.ConnectEdges () $.connectEdgeSegments = 1 $.setselection #edge edgesel macros.run "PolyTools" "GrowLoop" edgLoop1=polyop.getEdgeSelection $ $.setselection #edge edgesel $.setRingShift 2 true false $.EditablePoly.SelectEdgeLoop () edgShift2=polyop.getEdgeSelection $ $.setselection #edge (edgShift2+edgLoop1) sendkeys_CtrlRemove_fn() ) fn epSO_2_fn fco =( edgesel = fco.GetSelection #Edge if edgesel.numberset==0 then (PolyToolsModeling.Quadrify keyboard.shiftpressed keyboard.altpressed) else if keyboard.escPressed then MidChamfer_fn() else ( if edgesel.numberset==edgesel.count then Quadriangulate_fn()--PolyToolsModeling.Quadrify off off else sendkeys_CtrlRemove_fn() ) ) fn FaceReduce_fn fnO =( with Redraw off ( case classof fnO of ( Editable_Poly: (fnO.tesselateBy = 1 fnO.tessellate #Face) Edit_Poly: (fnO.tessellateByFace = 1 fnO.SetOperation #Tessellate fnO.Commit ()) ) fnO.ConvertSelectionToBorder #Face #Edge fnO.SetSelection #Face #{} case classof fnO of ( Editable_Poly: EdgeRemove_fn fco Edit_Poly: EdgeRemove_fn fco ) ) ) fn Overlap_Fn fco=( --OverlappingVertices.tolerance=0.01 if keyboard.escPressed then OverlappingVertices.showPropertyDlg() else ( V0=fco.getSelection #Vertex OverlapVerts=#() OverlappingVertices.Check currentTime selection[1] &OverlapVerts fco.SetSelection #Vertex #{} fco.SetSelection #Vertex (OverlapVerts as BitArray) fco.ConvertSelection #Vertex #Face requireAll:on fco.SetSelection #Vertex V0 subobjectLevel = 5 ) ) fn SO4_op_fn fco=( F0=fco.getSelection #Face if F0.count==F0.numberset then Overlap_Fn fco else if F0.numberset>0 then if keyboard.escPressed then FaceReduce_fn fco else ( EuF=polyop.getEdgesUsingFace $ (F0 as array) fco.SetSelection #Edge EuF EdgeRemove_fn fco --try fco.Remove selLevel:#Edge flag:1 catch fco.ButtonOp #RemoveEdge ) else ( deg = 60 /* defines the max angleDiff to straight up for selection */ with undo on for Obj in selection as array where isValidNode Obj AND superclassOf Obj == geometryClass do polyop.setFaceSelection Obj ((for f = 1 to Obj.numFaces collect (if acos (dot (polyOp.getFaceNormal Obj f node:Obj) (inverse(getViewTM())).row3) < deg /*OR acos (dot (polyOp.getFaceNormal Obj f node:Obj) -(inverse(getViewTM())).row3) < deg*/ then f else 1)) as bitArray) completeRedraw() ) --fco.SmGrpFloater() ) ---------------------------SCRIPT----------------------------------- fn selVert_fn=(sum=0; for i in (for i in selection collect (getVertSelection i.mesh).numberset) do sum=sum+i; sum) fn selEdge_fn=(sum=0; for i in (for i in selection collect (getEdgeSelection i.mesh).numberset) do sum=sum+i; sum) fn selface_fn=(sum=0; for i in (for i in selection collect (getFaceSelection i.mesh).numberset) do sum=sum+i; sum) if (MatEditor.isOpen() and getCommandPanelTaskMode() != #display and not (selection[1].category==#Standard_Primitives or (subobjectlevel==1 and selVert_fn()>0) or (subobjectlevel==2 and selEdge_fn()>0) or (subobjectlevel==4 and selface_fn()>0))) do ( fn Window_in_focus = ( local code = " using System; using System.Runtime.InteropServices; namespace MXS { class WinApi { [DllImport(\"user32.dll\")] public static extern IntPtr GetForegroundWindow(); } } " local csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider" local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters" compilerParams.GenerateInMemory = true compilerParams.ReferencedAssemblies.AddRange #("System.dll") local compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(code) if (compilerResults.Errors.Count > 0) then ( local errors = stringstream "" format "-- CSharpCodeProvider : Error while compiling:\n" to:errors for i = 0 to (compilerResults.Errors.Count-1) do ( err = compilerResults.Errors.Item[i] format "Error:% Line:% Column:% \"%\"\n" err.ErrorNumber err.Line err.Column err.ErrorText to:errors ) (dotnetclass "Autodesk.Max.MaxPlus.Core").WriteLine errors true ) compilerResults.CompiledAssembly.CreateInstance "MXS" local hwndFocusWindow = (dotNetClass "MXS.WinApi").GetForegroundWindow() ) DesktopChild=(windows.getChildrenHWND (windows.getDesktopHWND())) --clearlistener(); for i in DesktopChild do format "%\n" i if Window_in_focus()==(for i=1 to DesktopChild.count where (DesktopChild[i][5][1]=="M" and DesktopChild[i][5][2]=="a" and DesktopChild[i][5][3]=="t" and DesktopChild[i][5][15]=="r") do exit with DesktopChild[i][1]) -- Find "M" "a" "t" "r" in "Material Editor - 04 - Default" do ( meditmaterials[activeMeditSlot] = ( Standardmaterial name: ( ( if activeMeditSlot<10 then "0"+(activeMeditSlot as string) else (activeMeditSlot as string) )+" - Default") ) ) ) if getCommandPanelTaskMode() == #display do for i in selection do (i.material=undefined; i.xray = off) if getCommandPanelTaskMode() == #create then for i in selection as array where i.category != #Splines do (select i; FixResetObj_fn i; converttoPoly $; max modify mode; PushPrompt "Object was Reset by attach to mesh") max modify mode if selection.count==0 then actionMan.executeAction 0 "50026" -- Tools: Maximize Viewport Toggle else if (subObjectLevel==0 or subObjectLevel==undefined) then if keyboard.escPressed then case MaxRibbon.IsRibbonOpen() of ( true: MaxRibbon.ShowRibbon false false: MaxRibbon.ShowRibbon true ) else for obj in selection do ( if (classOf obj != Line and classOf obj != SplineShape and obj.category == #Splines) then convertToSplineShape obj else if (classOf obj == Line or classOf obj == SplineShape) then (fixShapeXform_fn obj; PushPrompt "Shape was fixed" --if obj.category == #Splines then if obj.render_displayRenderMesh==on then convertToPoly obj ) else if superclassof obj==GeometryClass and getCommandPanelTaskMode() != #display and getCommandPanelTaskMode() != #create and obj.modifiers.count==0 then if classof obj!=Editable_Poly then convertToPoly obj else obj.wirecolor = random black white ) --if selection.count==0 do select (maxOps.getNodeByHandle (amax (for o in objects collect o.inode.handle))) else ( gco = modPanel.getCurrentObject() case classOf gco of ( Editable_poly: ( tryInit gco case subobjectLevel of ( 1: if keyboard.EscPressed then SelVertbyAngleEdge_fn gco else epSO_1_fn gco 2: epSO_2_fn gco 3: (SetVertOpen_2e_fn gco; PushPrVertSel_fn gco) 4: SO4_op_fn gco 5: SO4_op_fn gco ) ) Edit_Poly: ( tryInit gco case subobjectLevel of ( 1: epSO_1_fn gco 2: sendkeys_CtrlRemove_fn() 3: (gco.SetSelection #Vertex #{} SetVertOpen_2e_fn gco; PushPrVertSel_fn gco) 4: SO4_op_fn gco 5: SO4_op_fn gco ) ) Line: if isEmpty_KNspl_fn() and subobjectlevel==1 then DOTselKnots_fn() else (V_state1 = numKnots $; RemSpl_fn gco; 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; V_state2=numKnots $; differV=V_state1-V_state2 if differV > 0 do PushPrompt (differV as string + " Knots removed")) Edit_Spline: (RemSpl_fn gco) ) ) if selection.count>0 do if selection[1].scale==[-1,-1,-1] then ( select (for i in selection where i.scale==[-1,-1,-1] collect i) for i in selection as array do (select i; FixResetObj_fn i; PushPrompt "Fixed scale [-1,-1,-1]") ) redrawviews() max select resumeediting() )