in your algorithm I see some logical mistake…
you want to smooth edges and you use NURMS Subdivision for that. It’s subdivides whole mesh but you actually need to subdivide only chamfered edges. The right way is to use polyop.meshSmoothByEdge
Hi Denis…Thanks again
I accept your suggestion
This is the script interface.
This may explain what I want to achieve.
if deRoll != undefined do try (destroyDialog deRoll) catch()
rollout deRoll " Deformed Edges"
(
fn filtObj obj = (isKindOf obj Editable_Poly and obj.modifiers.count == 0)
label deLbl0 " Pick and Prepare Object " pos:[0,0] width:160 height:16 style_sunkenedge:true
pickbutton deBtn0 "Pick E-Poly Object" pos:[2,18] width:136 height:18 tooltip:"Pick Editable Poly Object" filter:filtObj
button deBtn1 "C" pos:[140,18] width:18 height:18 tooltip:"Clear"
button deBtn2 "Select Hard Edges" pos:[2,38] width:136 height:18 tooltip:"Pick Editable Poly Object"
button deBtn3 "R" pos:[140,38] width:18 height:18 tooltip:"Reset Spinners"
spinner deSpn0 "MinAngle: " pos:[3,58] fieldwidth:60 height:16 range:[-360,360,60] type:#float
spinner deSpn1 "MaxAngle: " pos:[2,76] fieldwidth:60 height:16 range:[-360,360,120] type:#float
label deLbl1 " Deform Options " pos:[0,94] width:160 height:16 style_sunkenedge:true
button deBtn4 "Click to Analize Topology" pos:[2,112] width:156 height:18 tooltip:"Pick Editable Poly Object"
label deLbl2 " > object need to be analized!" pos:[0,132] width:160 height:16
spinner deSpn2 "Chamfer Amount:" pos:[2,150] fieldwidth:60 height:16 range:[0.001,1e3,1] type:#float
spinner deSpn3 "Edge Division: " pos:[2,168] fieldwidth:60 height:16 range:[1,10,3] type:#float
spinner deSpn4 "Vertex Offset: " pos:[2,186] fieldwidth:60 height:16 range:[0,1e4,0.1] type:#float
button deBtn5 "Random Seed" pos:[2,204] width:85 height:16 tooltip:"Pick Editable Poly Object"
spinner deSpn5 "" pos:[87,204] fieldwidth:60 height:16 range:[0e6,9e6,123456] type:#integer
checkbox deCb0 "Use Interactive Mode" pos:[2,222] width:156 height:16
button deBtn6 "Revert Object Topology" pos:[2,240] width:156 height:18
button deBtn7 "Deform Hard Edges" pos:[2,260] width:156 height:18
)
createdialog deRoll 160 280 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)
With button “Click to Analize Topology” pressed i will get next info:
–> Poly Count (with this info the script decide when the user can use “interactive mode”
and disable or enable checkbox ) and number of elements (if obj have multiple element)
–> Number of selected edges and longest edge in selection
(i think that is smart move to lighter up main function)
–>Do a snapshot as mash of picked object (for Revert object topology)
I’ll add funcions and events later.
What do you think?
originally posted by DenisT
you want to smooth edges and you use NURMS Subdivision for that. It’s subdivides whole mesh but you actually need to subdivide only chamfered edges. The right way is to use polyop.meshSmoothByEdge
Use NURMS Subdivision is only for preview.
Look script interface. I remove that.
Here is my work in progress.
global deRoll
if deRoll != undefined do try (destroyDialog deRoll) catch()
rollout deRoll " Deformed Edges v1.0"
(
local defObj, selEdges, backupObj
local IneractiveMode = false
local divisionsArr = #()
local backupObj
fn filtObj obj = (isKindOf obj Editable_Poly and obj.modifiers.count == 0)
fn edgeFacesAngle dir1 dir2 = (acos (dot (normalize dir2) (normalize dir1)))
fn getSnapshot obj =
(
smesh = (p = convertToPoly (snapshot obj)).mesh
delete p ; smesh
)
fn selectHardEdges obj minAngle maxAngle =
(
local edgelist = #{}
getedgefaces = polyOp.getEdgeFaces
getFnormal = polyop.getFaceNormal
edgeCnt = polyop.getNumEdges obj
for ed in 1 to edgeCnt where (getedgefaces obj ed).count == 2 do
(
facesArr = (getedgefaces obj ed)
dir1 = (getFnormal obj facesArr[1])
dir2 = (getFnormal obj facesArr[2])
theAngle = edgeFacesAngle dir1 dir2
if theAngle >= minAngle and theAngle <= maxAngle do append edgelist ed
)
if edgelist.numberSet != 0 do
(
obj.selectededges = edgelist
if getCommandPanelTaskMode() != #modify do setCommandPanelTaskMode mode:#modify
modPanel.setCurrentObject obj ; subobjectLevel = 2
)
)
fn calculateDivisions obj edgeslist divVal =
(
getedgeverts = polyOp.getEdgeVerts
getvertpos = polyOp.getVert
edgeLenghts = for edge in edgeslist collect
(
vv = getedgeverts obj edge
distance (getvertpos obj vv[1]) (getvertpos obj vv[2])
)
maxEdgesLength = amax edgeLenghts
for eLength in edgeLenghts collect ((ceil (eLength / (maxEdgesLength/divVal)))-1) as integer
)
fn deformEdges obj edgelist divideArr chamferAmount: rand: seedValue: =
(
seed seedValue ; id = 0
chamferedges = polyOp.chamferEdges
getedgeverts = polyOp.getEdgeVerts
movevert = polyOp.moveVert
divideedge = polyOp.divideEdge
getnumedges = polyOp.getNumEdges
getvertpos = polyOp.getVert
for edge in edgelist do --divide edges
(
divideIdx = divideArr[id += 1]
if divideIdx != 0 do ( for d = divideIdx to 1 by -1.0 do divideedge obj edge (1 - 1/(d+1)) )
)
chamferedges obj obj.selectededges chamferAmount -- chamfer edge with given a value
verts = polyOp.getVertsUsingEdge obj obj.selectededges
for v in verts do movevert obj v (random -rand rand)
polyOp.retriangulate obj obj.faces -- retriangulate faces
polyOp.setFaceSmoothGroup obj obj.faces 0 -- clear SmoothGroup
)
label deLbl0 " Pick and Prepare Object " pos:[0,0] width:160 height:16 style_sunkenedge:true
pickbutton deBtn0 "Pick E-Poly Object" pos:[2,18] width:136 height:18 tooltip:"Pick Editable Poly Object" filter:filtObj
button deBtn1 "C" pos:[140,18] width:18 height:18 tooltip:"Clear"
button deBtn2 "Select Hard Edges" pos:[2,38] width:136 height:18 tooltip:"Pick Editable Poly Object"
button deBtn3 "R" pos:[140,38] width:18 height:18 tooltip:"Reset Angle Spinners"
spinner deSpn0 "MinAngle: " pos:[3,58] fieldwidth:60 height:16 range:[-360,360,60] type:#float
spinner deSpn1 "MaxAngle: " pos:[2,76] fieldwidth:60 height:16 range:[-360,360,120] type:#float
label deLbl1 " Deform Options " pos:[0,94] width:160 height:16 style_sunkenedge:true
button deBtn4 "Click to Analize Topology" pos:[2,112] width:156 height:18 tooltip:"Pick Editable Poly Object"
label deLbl2 " > object need to be analized!" pos:[0,132] width:160 height:16
spinner deSpn2 "Chamfer Amount:" pos:[2,150] fieldwidth:60 height:16 range:[0.001,1e3,1] type:#float
spinner deSpn3 "Edge Division: " pos:[2,168] fieldwidth:60 height:16 range:[1,10,3] type:#float
spinner deSpn4 "Vertex Offset: " pos:[2,186] fieldwidth:60 height:16 range:[0,1e4,0.1] type:#float
button deBtn5 "Random Seed" pos:[2,204] width:85 height:16 tooltip:"Pick Editable Poly Object"
spinner deSpn5 "" pos:[87,204] fieldwidth:60 height:16 range:[0e6,9e6,123456] type:#integer
checkbox deCb0 "Use Interactive Mode" pos:[2,222] width:156 height:16 enabled:false
button deBtn6 "Revert Object Topology" pos:[2,240] width:156 height:18 enabled:false
button deBtn7 "Deform Hard Edges" pos:[2,260] width:156 height:18 enabled:false
/*
on deSpn2 changed val do --Chamfer Amount
(
if deCb0.checked == true do
(
--REVERT OBJECT HERE
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:val rand:offset seedValue:deSpn5.value
)
)
on deSpn3 changed val do --Edge Division
(
if deCb0.checked == true do
(
--REVERT OBJECT HERE
divisionsArr = calculateDivisions defObj selEdges val
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
)
)
on deSpn4 changed val do --Vertex Offset
(
if deCb0.checked == true do
(
--REVERT OBJECT HERE
offset = [val,val,val]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
)
)
on deSpn5 changed val do --Random Seed
(
if deCb0.checked == true do
(
--REVERT OBJECT HERE
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:val
)
)*/
on deBtn0 picked obj do --Pick E-Poly Object
(
if isValidNode obj == true do
(
deBtn0.text = obj.name
defObj = obj
backupObj = getSnapshot obj
)
)
on deBtn1 pressed do (deBtn0.text = "Pick E-Poly Object" ; defObj = undefined) --Clear
on deBtn2 pressed do --Select Hard Edges
(
if isValidNode defObj do (selectHardEdges defObj deSpn0.value deSpn1.value)
)
on deBtn3 pressed do (deSpn0.value = 60 ; deSpn1.value = 120) --Reset Angle Spinners
on deBtn4 pressed do --Click to Analize Topology
(
if isValidNode defObj do
(
selEdges = defObj.selectededges as bitarray
if selEdges.numberSet == 0 then (#abort ; messageBox "Select edges first!" title:"Warning" beep:false) else
(
deBtn7.enabled = true
deLbl2.text = " > ready for deformation!"
divisionsArr = calculateDivisions defObj selEdges deSpn3.value
polyCount = polyOp.getNumEdges defObj
if polyCount >= 1e6 do (messageBox ("Object polygon count is "+polyCount as string+"
Not recommended to use interactive mode") title:"Warning" beep:false)
)
)
)
on deBtn5 pressed do (deSpn5.value = random 100000.0 999999) --Random Seed
on deBtn6 pressed do --Revert Object Topology
(
if isValidNode defObj and classof backupObj == TriMesh do
(
defObj.baseobject = backupObj
deBtn7.enabled = true
deBtn6.enabled = deCb0.enabled = deCb0.checked = false
)
)
on deBtn7 pressed do
(
if isValidNode defObj and selEdges.numberSet != 0 do
(
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
t1 = timestamp() ; m1 = heapfree
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
format "time:% memory:%
" (timestamp() - t1) (m1 - heapfree)
deBtn6.enabled = deCb0.enabled = true
deBtn7.enabled = false
)
)
)
createdialog deRoll 160 280 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)
Changes:
–Main function is optimized by removing division calculation.
–I decide to separately calculate divisions for each selected edge
and place result in array by using function “calculateDivisions”.
–Performing the test on the same model i got this result (time:49 memory:20832L)
–The settings I used are shown in the image below
The following are the things where I got stuck.
1st “Revert Object Topology” button, and 2nd “Use Interactive Mode”.:shrug:
I try with this in Lisener:
originalObj = $Box001 --(already converted to editpoly)
beckupObj = node
--Now i use this function
fn getSnapshot obj &backupObj =
(
backupObj = (p = copy obj).mesh
delete p
)
beckupObj = getSnapshot originalObj
--Then i deform and change topology of the "Box001"
--To back to original shape (form), I used
originalObj.baseobject = beckupObj
This work fine in listener but when i use this in the script then i recive this:
-- Error occurred in deBtn6.pressed(); filename: D:\Temp\Deformed Edges.ms; position: 5531; line: 126
-- [color=Blue]Frame:[/color]
>> MAXScript Rollout Handler Exception:
-- Unknown system exception <<
Any new suggestion or method for *Reverting object topology* and *Interactive Mode*?
Thanks in advance
Work in progress (part2)
Hi guys,
I solved *Reverting object topology* problem for returning the model to it’s original state.
Also Interactive Mode now works, but is not recommended to be used on high poly models.
Added use NURMS subdivision only as preview mode.
I use timer control to reset all paremeters to default when the model is removed from the script or deleted from the scene.
Any suggestion for optimization or upgrade are welcome.
All credits go Denis Trofimov (Denis T) that helped me to solve this “puzzle”.
Regards!
global deRoll
if deRoll != undefined do try (destroyDialog deRoll) catch()
rollout deRoll " Deformed Edges v1.0a"
(
global backupObj = undefined
local defObj, selEdges, polyCount, ctrlState
local divisionsArr = #()
fn filtObj obj = (isKindOf obj Editable_Poly and obj.modifiers.count == 0)
fn edgeFacesAngle dir1 dir2 = (acos (dot (normalize dir2) (normalize dir1)))
fn getSnapshot obj &backupObj =
(
backupObj = (p = copy obj).baseobject
delete p
)
fn selectHardEdges obj minAngle maxAngle =
(
local edgelist = #{}
getedgefaces = polyOp.getEdgeFaces
getFnormal = polyop.getFaceNormal
edgeCnt = polyop.getNumEdges obj
for ed in 1 to edgeCnt where (getedgefaces obj ed).count == 2 do
(
facesArr = (getedgefaces obj ed)
dir1 = (getFnormal obj facesArr[1])
dir2 = (getFnormal obj facesArr[2])
theAngle = edgeFacesAngle dir1 dir2
if theAngle >= minAngle and theAngle <= maxAngle do append edgelist ed
)
if edgelist.numberSet != 0 do
(
obj.selectededges = edgelist
if getCommandPanelTaskMode() != #modify do setCommandPanelTaskMode mode:#modify
modPanel.setCurrentObject obj ; subobjectLevel = 2
)
)
fn calculateDivisions obj edgeslist divVal =
(
getedgeverts = polyOp.getEdgeVerts
getvertpos = polyOp.getVert
edgeLenghts = for edge in edgeslist collect
(
vv = getedgeverts obj edge
distance (getvertpos obj vv[1]) (getvertpos obj vv[2])
)
maxEdgesLength = amax edgeLenghts
for eLength in edgeLenghts collect ((ceil (eLength / (maxEdgesLength/divVal)))-1) as integer
)
fn deformEdges obj edgelist divideArr chamferAmount: rand: seedValue: =
(
seed seedValue ; id = 0
chamferedges = polyOp.chamferEdges
getedgeverts = polyOp.getEdgeVerts
movevert = polyOp.moveVert
divideedge = polyOp.divideEdge
getnumedges = polyOp.getNumEdges
getvertpos = polyOp.getVert
for edge in edgelist do --divide edges
(
divideIdx = divideArr[id += 1]
if divideIdx != 0 do ( for d = divideIdx to 1 by -1.0 do divideedge obj edge (1 - 1/(d+1)) )
)
chamferedges obj obj.selectededges chamferAmount -- chamfer edge with given a value
verts = polyOp.getVertsUsingEdge obj obj.selectededges
for v in verts do movevert obj v (random -rand rand)
polyOp.retriangulate obj obj.faces -- retriangulate faces
polyOp.setFaceSmoothGroup obj obj.faces 0 -- clear SmoothGroup
)
label deLbl0 " Pick and Prepare Object " pos:[0,0] width:160 height:16 style_sunkenedge:true
pickbutton deBtn0 "Pick E-Poly Object" pos:[2,18] width:136 height:18 tooltip:"Pick Editable Poly Object" filter:filtObj
button deBtn1 "C" pos:[140,18] width:18 height:18 tooltip:"Clear"
button deBtn2 "Select Hard Edges" pos:[2,38] width:136 height:18 tooltip:"Pick Editable Poly Object"
button deBtn3 "R" pos:[140,38] width:18 height:18 tooltip:"Reset Angle Spinners"
spinner deSpn0 "MinAngle: " pos:[3,58] fieldwidth:60 height:16 range:[-360,360,60] type:#float
spinner deSpn1 "MaxAngle: " pos:[2,76] fieldwidth:60 height:16 range:[-360,360,120] type:#float
label deLbl1 " Deform Options " pos:[0,94] width:160 height:16 style_sunkenedge:true
button deBtn4 "Click to Analize Topology" pos:[2,112] width:156 height:18 tooltip:"Pick Editable Poly Object"
label deLbl2 " > object need to be analized!" pos:[0,132] width:160 height:16
spinner deSpn2 "Chamfer Amount:" pos:[2,150] fieldwidth:60 height:16 range:[0.001,1e3,1] type:#float
spinner deSpn3 "Edge Division: " pos:[2,168] fieldwidth:60 height:16 range:[1,10,3] type:#integer
spinner deSpn4 "Vertex Offset: " pos:[2,186] fieldwidth:60 height:16 range:[0,1e4,0.1] type:#float
button deBtn5 "Random Seed" pos:[2,204] width:85 height:16 tooltip:"Pick Editable Poly Object"
spinner deSpn5 "" pos:[87,204] fieldwidth:60 height:16 range:[0e6,9e6,123456] type:#integer
checkbutton deBtn6 "Preview UNS" pos:[2,222] width:85 height:16 tooltip:"Use NURMS Sudivision"
spinner deSpn6 "" pos:[87,222] fieldwidth:60 height:16 range:[0,5,2] type:#integer tooltip:"Display Iterations"
checkbox deCb0 "Use Interactive Mode" pos:[2,240] width:156 height:16 enabled:false
button deBtn7 "Revert Object Topology" pos:[2,260] width:156 height:18 enabled:false
button deBtn8 "Deform Hard Edges" pos:[2,280] width:156 height:18 enabled:false
timer clock "Reseter" interval:100 active:false
fn resetAllCtrls =
(
deBtn0.text = "Pick E-Poly Object"
deLbl2.text = " > object need to be analized!"
deSpn0.value = 60
deSpn1.value = 120
deSpn2.value = 1
deSpn3.value = 3
deSpn4.value = 0.1
deSpn5.value = 123456
deSpn6.value = 2
deBtn6.checked = deCb0.checked = deCb0.enabled = deBtn7.enabled = deBtn8.enabled = false
defObj = undefined ; backupObj = undefined
free selEdges ; free divisionsArr ; gc()
)
on deBtn0 picked obj do --Pick E-Poly Object
(
if isValidNode obj == true do
(
deBtn0.text = obj.name
getSnapshot obj &backupObj
defObj = obj
clock.active = true
)
)
on deBtn1 pressed do (resetAllCtrls())--Clear
on deBtn2 pressed do --Select Hard Edges
(
if isValidNode defObj do (selectHardEdges defObj deSpn0.value deSpn1.value)
)
on deBtn3 pressed do (deSpn0.value = 60 ; deSpn1.value = 120) --Reset Angle Spinners
on deBtn4 pressed do --Click to Analize Topology
(
if isValidNode defObj do
(
selEdges = defObj.selectededges as bitarray
if selEdges.numberSet == 0 then (#abort ; messageBox "Select edges first!" title:"Warning" beep:false) else
(
deBtn8.enabled = true
deLbl2.text = " > ready for deformation!"
divisionsArr = calculateDivisions defObj selEdges deSpn3.value
polyCount = polyOp.getNumEdges defObj
if polyCount >= 1e4 do (messageBox ("Object polygon count is "+polyCount as string+"
Not recommended to use interactive mode") title:"Warning" beep:false)
)
)
)
on deSpn2 changed val do --Chamfer Amount
(
if deCb0.checked == true do
(
if polyOp.getNumEdges defObj != polyCount do
(
defObj.baseobject = backupObj
getSnapshot defObj &backupObj
defObj.selectededges = selEdges
)
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:val rand:offset seedValue:deSpn5.value
)
)
on deSpn3 changed val do --Edge Division
(
if deCb0.checked == true do
(
if polyOp.getNumEdges defObj != polyCount do
(
defObj.baseobject = backupObj
getSnapshot defObj &backupObj
defObj.selectededges = selEdges
)
divisionsArr = calculateDivisions defObj selEdges val
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
)
)
on deSpn4 changed val do --Vertex Offset
(
if deCb0.checked == true do
(
if polyOp.getNumEdges defObj != polyCount do
(
defObj.baseobject = backupObj
getSnapshot defObj &backupObj
defObj.selectededges = selEdges
)
offset = [val,val,val]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
)
)
on deBtn5 pressed do --Random Seed
(
deSpn5.value = random 100000.0 999999
if deCb0.checked == true do
(
if polyOp.getNumEdges defObj != polyCount do
(
defObj.baseobject = backupObj
getSnapshot defObj &backupObj
defObj.selectededges = selEdges
)
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
)
)
on deSpn5 changed val do --Random Seed
(
if deCb0.checked == true do
(
if polyOp.getNumEdges defObj != polyCount do
(
defObj.baseobject = backupObj
getSnapshot defObj &backupObj
defObj.selectededges = selEdges
)
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:val
)
)
on deBtn6 changed state do -- Preview: Use NURMS Sudivision
(
if isValidNode defObj do
(
local ctrlArr = #(deCb0,deBtn7,deBtn8)
if state == on then
(
defObj.surfSubDivide = on ; defObj.iterations = deSpn6.value
ctrlState = for c in ctrlArr collect (c.enabled) ; append ctrlState ctrlArr[1].checked
format "%
" ctrlState
deCb0.enabled = deCb0.checked = deBtn7.enabled = deBtn8.enabled = false
)
else
(
defObj.surfSubDivide = off
for i in 1 to 3 do (ctrlArr[i].enabled = ctrlState[i])
ctrlArr[1].checked = ctrlState[4]
)
)
)
on deSpn6 changed val do --Display Iterations
(
if isValidNode defObj and deBtn6.checked == true do defObj.iterations = val
)
on deBtn7 pressed do --Revert Object Topology
(
if isValidNode defObj do
(
format "%
" backupObj
defObj.baseobject = backupObj
getSnapshot defObj &backupObj
defObj.selectededges = selEdges
setCommandPanelTaskMode mode:#modify
subobjectLevel = 2 ; deBtn8.enabled = true
deBtn7.enabled = deCb0.enabled = deCb0.checked = false
)
)
on deBtn8 pressed do
(
if isValidNode defObj and selEdges.numberSet != 0 do
(
offset = [deSpn4.value,deSpn4.value,deSpn4.value]
if getCommandPanelTaskMode() != #create do setCommandPanelTaskMode mode:#create
t1 = timestamp() ; m1 = heapfree
undo off deformEdges defObj selEdges divisionsArr chamferAmount:deSpn2.value rand:offset seedValue:deSpn5.value
format "time:% memory:%
" (timestamp() - t1) (m1 - heapfree)
deBtn7.enabled = deCb0.enabled = true
deBtn8.enabled = false
)
)
on clock tick do (if not isValidNode (getNodeByName deBtn0.text) do (resetAllCtrls() ; clock.active = false))
on deRoll close do (backupObj = undefined ; gc() ; clearListener())
)
createdialog deRoll 160 300 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)
I think this tool will be useful to someone.
I would like to see your comment or criticism after all.
Finished script Deformed Edges can be found at this address:
http://www.scriptspot.com/3ds-max/scripts/deformed-edges
Cheers!
Script is updated to version 1.1
Version 1.1 New Features:
- now you can use BEVEL operation to create a stitches
NOTE: To disable bevel option just set Bevel Height value to ZERO. - added Preview Checker Map options for cheking the model UV’s.
Link: Deformed Edges v1.1