Files
2025-09-29 00:52:08 +02:00

544 lines
13 KiB
Plaintext
Executable File

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