544 lines
13 KiB
Plaintext
Executable File
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
|
|
|
|
|