struct Strct_RockInsetTool ( MyRollout, FaceNm, MyObject, insetAmount=0.01, count = 0, FaceSmthArr, smoothLevel = 30, SmtBorders = #(), EdgeToDelete = #(), VertPerFace = #(), SixVertFace = #(), TempTestArray = #(), TempTestArray2 = #(), IDArr = #(), SaveMatObject, -- I get the smoothing groups fn RSTA_Get_Smth_Groups = ( --get number of faces FaceNm = polyop.getNumFaces MyObject --get all the smoothing groups used by our faces FaceSmthArr = #() For iFace = 1 to FaceNm do ( smgrpFaces = polyop.getFaceSmoothGroup MyObject iFace --if one face have no smoothing group, assing 1 by default if smgrpFaces == 0 then ( -- polyop.setFaceSmoothGroup MyObject iFace 1 smgrpFaces = 1 appendifunique FaceSmthArr smgrpFaces ) else ( appendifunique FaceSmthArr smgrpFaces ) ) return FaceSmthArr ), -- II select faces per smoothing group, detach them... and inset. fn RSTA_DetachFacesAndInset = ( --activate preserveUVs MyObject.preserveUVs = on For iSmthG = 1 to FaceSmthArr.count do ( SmthG = FaceSmthArr[iSmthG] MyObject.selectBySmoothGroup SmthG clearCurrentSelection:true mySelection = polyop.getFaceSelection MyObject count += 1 --Update Progress Bar if MyRollout != undefined do ( MyRollout.pgr_InsetProg.value = 100.*count/FaceSmthArr.count ) --Detache polyop.detachFaces MyObject mySelection delete:true asNode:true name:("InsetPart"+ (count as string)) --Select new detached obj clearSelection() InsetObj = getnodebyname ("InsetPart"+ (count as string)) if InsetObj != undefined then ( select InsetObj max modify mode subobjectLevel = 4 -- activate Preserv UVs InsetObj.preserveUVs = on ) -- inset setup InsetObj.insetAmount = insetAmount InsetObj.insetType = 0 InsetObj.EditablePoly.buttonOp #Inset --clear selection InsetObj.EditablePoly.SetSelection #Face #{} --Re-attach polyop.attach Strct_RockInsetTool.MyObject InsetObj ) ), fn RSTA_CleanMesh = ( --get all verts VertCount = MyObject.GetNumVertices () VertCountBArr = #{1..VertCount} --weld verts MyObject.weldThreshold = 0.01 polyop.weldVertsByThreshold MyObject VertCountBArr EdgeBorder =#() For iSmthG = 1 to FaceSmthArr.count do ( SmthG = FaceSmthArr[iSmthG] subobjectLevel = 4 MyObject.selectBySmoothGroup SmthG clearCurrentSelection:true --I --Save Smooth Border ( to make sure we don't delete thoses edge later on) mySelection = polyop.getFaceSelection MyObject --Get Face borders MyObject.EditablePoly.ConvertSelectionToBorder #Face #Edge SmthEdgeBorder = polyop.getEdgeSelection MyObject SmthEdgeBorderArr = (SmthEdgeBorder as array) for edgei = 1 to SmthEdgeBorderArr.count do ( thEdge = SmthEdgeBorderArr[edgei] appendifunique SmtBorders thEdge ) subobjectLevel = 4 --II --Get Inside edge between insets MyObject.EditablePoly.GrowSelection () mySelection = polyop.getFaceSelection MyObject --Get Face borders MyObject.EditablePoly.ConvertSelectionToBorder #Face #Edge EdgeBorder = polyop.getEdgeSelection MyObject EdgeBorderArr = (EdgeBorder as array) for edgei = 1 to EdgeBorderArr.count do ( thEdge = EdgeBorderArr[edgei] appendifunique EdgeToDelete thEdge ) ) --III --Substract SmtBorders to EdgeToDelete to make sure we are not deleting original smooth border faces theDifference=(EdgeToDelete as bitarray - SmtBorders as bitarray)as bitarray EdgeToDelete = (theDifference as bitarray) -- IV --Selected and Destroy subobjectLevel = 2 --activate preserveUVs MyObject.preserveUVs = on MyObject.EditablePoly.SetSelection #Edge theDifference --with this method we simply don't touch the edges on the border of the mesh try ( MyObject.EditablePoly.Remove () )catch() -- V -- Find 6 edges faces, find their closest non-conected verts, conect them. result == 1 quad 2 triangle -- isolate every 6 edged faces. FaceNm = polyop.getNumFaces MyObject For Facei = 1 to FaceNm do ( VertPerFace = polyop.getFaceVerts MyObject Facei --if the face have 6 verts isolate it, forget about the other ones -- just get its verts, no need for face id if VertPerFace.count == 6 do ( append SixVertFace VertPerFace ) ) -- Get verts coordinates per faces , get the closest, conect them For Vertarri = 1 to SixVertFace.count do ( VertArr = SixVertFace[Vertarri] TempArry = #() VertIDarr = #() for Verti = 1 to VertArr.count do ( TheVert = VertArr[Verti] VertCoord = polyop.getVert MyObject TheVert append TempArry VertCoord append VertIDarr TheVert ) -- get distance between verts DistanceArr = #() For VertCoori = 2 to TempArry.count do ( VertCoordA = TempArry[VertCoori] VertCoordB = TempArry[VertCoori-1] VertDistance = distance VertCoordB VertCoordA append DistanceArr VertDistance ) -- DistanceArr == collection of edge. First item == 2 first item of VertIDarr, 2nd item == 2 and 3thrd item of VertIDarr and so on. -- Which ones are our 2 longest edges ? sortedDistanceArr = deepcopy DistanceArr sort sortedDistanceArr -- get the two last items TwoBigest = #() Last = sortedDistanceArr.count BigestA = sortedDistanceArr[Last] BigestB = sortedDistanceArr[Last-1] -- Which edges in the unsorted array ? EdgeAitem = findItem DistanceArr BigestA EdgeBitem = findItem DistanceArr BigestB --Which verts in VertIDarr for thoses two edges ? VertsToConect = #() append VertsToConect VertIDarr[EdgeAitem] append VertsToConect VertIDarr[EdgeAitem+1] append VertsToConect VertIDarr[EdgeBitem] append VertsToConect VertIDarr[EdgeBitem+1] --select and connect all those verts subobjectLevel = 1 clearSelction = #{} polyop.setVertSelection MyObject clearSelction MyObject.preserveUVs = on polyop.setVertSelection MyObject (VertsToConect as bitarray) MyObject.EditablePoly.ConnectVertices () ) ), -- apply 1 color per smoothing group fn RSTA_SetColor_SmoothingGroups = ( max modify mode subobjectLevel = 4 --I Create multi-subObject standar material with as many as sub as smoothing group meditMaterials[24] = Multimaterial () meditMaterials[24].name = "ColourGuides" meditMaterials[24].numsubs = FaceSmthArr.count For Colori = 1 to FaceSmthArr.count do ( meditMaterials[24].materialList[Colori].Diffuse = color (random 1 255) (random 1 255) (random 1 255) ) --II Get and keep in memory the curently applied shader : Same thing with ID's --get applied material SaveMatObject = MyObject.mat --get number of faces FaceNm = polyop.getNumFaces MyObject --get mat ID per Face. for Idi = 1 to FaceNm do ( ID = MyObject.GetFaceMaterial Idi append IDArr ID ) --III Apply one ID per Smoothing group and then apply the colorfull multi sub obj shader --Select faces per smoothing groups and give them an ID For smthi = 1 to FaceSmthArr.count do ( SmthG = FaceSmthArr[smthi] MyObject.selectBySmoothGroup SmthG clearCurrentSelection:true mySelection = polyop.getFaceSelection MyObject polyop.setFaceMatID MyObject mySelection smthi MyObject.EditablePoly.SetSelection #Face #{} ) --apply the color table material MyObject.material = meditMaterials[24] ), -- Put the original ID and shader back fn RSTA_RemoveColor_SmoothingGroups = ( -- put back the original ID's for Idi = 1 to FaceNm do ( polyop.setFaceMatID MyObject Idi IDArr[Idi] ) --re-assign original material MyObject.material = SaveMatObject ), fn RSTA_ClearSmoothingGroups = ( addModifier MyObject (Smooth autosmooth: off) MyObject.modifiers[#Smooth].smoothingBits = 1 maxOps.CollapseNodeTo MyObject 1 off completeRedraw() ) ) Strct_RockInsetTool = Strct_RockInsetTool() rollout RockInsetTool "RockInsetTool" ( Group "Live Auto Smooth" ( Button btn_ClearSmth "Clear All" width:125 height:30 align:#right offset:[0,2] toolTip:"Clear the mesh from any smoothing groups" checkButton btn_AutSmth "Auto Smooth" width:125 height:30 align:#right offset:[0,2] toolTip:"Auto Smooth live editing" spinner spn_SmthLevel "Smooth Level" range:[0,100,30] offset:[0,5] toolTip:"Smoothing group threshold" checkButton btn_Color "Color Guides" width:125 height:30 align:#right offset:[0,2] toolTip:"Apply one colour per smothing group" ) Group "Inset" ( Button btn_Inst "Inset Smoothing Groups" width:125 height:30 align:#right offset:[0,2] toolTip:"Inset between the mesh smoothing groups" spinner spn_insetAmount "Inset Amount" range:[0,100,0.01] offset:[0,2] toolTip:"Inset threshold" ) label ProgBar "progress" offset:[-40,0] progressbar pgr_InsetProg color:red offset:[0,-2] -- a red progress bar on RockInsetTool Open do ( --instanciate rollout in struct if Strct_RockInsetTool != undefined do ( Strct_RockInsetTool.MyRollout = RockInsetTool ) spn_SmthLevel.enabled = false ) on btn_ClearSmth pressed do ( if selection[1] != undefined then ( MyObject = selection[1] addModifier MyObject (Smooth autosmooth: off) maxOps.CollapseNodeTo MyObject 1 off ) else ( print "no selection" ) ) on btn_Color changed state do ( if selection[1] != undefined then ( if state == true do ( displayColor.shaded = #material Strct_RockInsetTool.MyObject = selection[1] Strct_RockInsetTool.FaceSmthArr = Strct_RockInsetTool.RSTA_Get_Smth_Groups() Strct_RockInsetTool.RSTA_SetColor_SmoothingGroups() ) if state == false do ( displayColor.shaded = #object Strct_RockInsetTool.RSTA_RemoveColor_SmoothingGroups() ) ) else ( print "no selection" ) ) on btn_AutSmth changed state do ( if selection[1] != undefined then ( if state == true do ( spn_SmthLevel.enabled = true btn_ClearSmth.enabled = false btn_Inst.enabled = false spn_insetAmount.enabled = false btn_Color.enabled = false undo off Strct_RockInsetTool.MyObject = selection[1] addModifier Strct_RockInsetTool.MyObject (Smooth autosmooth: off) Strct_RockInsetTool.MyObject.modifiers[#Smooth].autosmooth = on Strct_RockInsetTool.MyObject.modifiers[#Smooth].preventIndirect = off ) if state == false do ( spn_SmthLevel.enabled = false btn_ClearSmth.enabled = true btn_Inst.enabled = true spn_insetAmount.enabled = true btn_Color.enabled = true maxOps.CollapseNodeTo Strct_RockInsetTool.MyObject 1 off completeRedraw() ) )else(print "no selection") ) on spn_SmthLevel changed arg do ( if selection[1] != undefined then ( Strct_RockInsetTool.smoothLevel = arg Strct_RockInsetTool.MyObject.modifiers[#Smooth].Threshold = Strct_RockInsetTool.smoothLevel ) else ( print "no selection" ) ) on spn_insetAmount changed arg do ( Strct_RockInsetTool.insetAmount = arg ) on btn_Inst pressed do ( if selection[1] != undefined then ( undo off disableSceneRedraw() Strct_RockInsetTool.MyObject = selection[1] -- I get the smoothing groups Strct_RockInsetTool.FaceSmthArr = Strct_RockInsetTool.RSTA_Get_Smth_Groups() -- II select faces per smoothing group, detach them... and inset. max modify mode subobjectLevel = 4 Strct_RockInsetTool.RSTA_DetachFacesAndInset() -- III clear the smoothing groups select Strct_RockInsetTool.MyObject subobjectLevel = 0 --Clean the mesh Strct_RockInsetTool.RSTA_CleanMesh() --Set all faces to smoothing Group 1 Strct_RockInsetTool.RSTA_ClearSmoothingGroups() --Update Progress Bar pgr_InsetProg.value = 0 -- when ready, reset the progress bar to 0% undo on enableSceneRedraw() ) else ( print "no selection" ) ) ) createDialog RockInsetTool 150 300