[Closed] mxs autowelder help
Hello guys.
I am not such a great maxscripter. I was trying to create a maxscript to help me on the retopology process but with no success. Basically i wanted to create a auto-weld option with a spinner or slider for the threshold. As it is in Maya (image below)
Now, for instance, after i created a new polygon with the extend tool (from the ribbon -freeform) and then if i selected a vertex and trying to get closer to another vertex i want them to weld automatically (based on the distance threshold setting). It is possible ? Can you guys help me on this?
Thanks!
This should be enough for you to get started.
If you find a way to reduce the amount of distance checks it could also be used with highpoly meshes
btw Can someone show how to make it undoable?
fn OnGeometryChanged ev nodes = (
if subObjectLevel != 1 or ev != #geometryChanged do return false
local obj = getAnimByHandle nodes[1]
local threshold = 5.0
if classof obj == Editable_Poly do (
local vsel = polyop.getVertSelection obj as array
if vsel.Count == 0 do return false
--
sort vsel
for j = vsel.count to 1 by -1 do (
pt = polyop.getVert obj vsel[j]
for i = polyop.getNumVerts obj to 1 by -1 where (d = distance pt (pt2 = polyop.getVert obj i)) <= threshold do (
if i != vsel[j] do (
format "welding.. % and %
" i vsel[j]
polyop.weldVerts obj vsel[j] i pt2
)
)
)
--
)
format "event: %
" ev
format "%
" nodes
)
if isKindOf callback Value do (
callback.Enabled = false
callback = undefined
gc light:true
format "callback reset
"
)
callback = NodeEventCallback mouseUp:true geometryChanged:OnGeometryChanged
Hey! Thanks.
I modified a little bit (added UI and undo). Recommended to not use a high value for the threshold. Otherwise the script will crash:)
Here is the code:
try(destroydialog autowelder)catch()
rollout autowelder ""
(
checkbox cb01 "Auto-weld"
slider sld01 "" pos:(cb01.pos+[110,0]) type:#float ticks:0 width:80 range:[0.1,5,1]
edittext txt01 "" pos:(cb01.pos +[68,0]) width:35 text:(sld01.value as string)
on sld01 changed state do ( txt01.text = (sld01.value as string) )
on txt01 changed state do ( sld01.value = (txt01.text as float) )
on cb01 changed state do (
with undo on (
if $ != undefined then
(
fn OnGeometryChanged ev nodes =
(
if subObjectLevel != 1 or ev != #geometryChanged or cb01.checked == false do return false
local obj = getAnimByHandle nodes[1]
local threshold = sld01.value
if classof obj == Editable_Poly do (
local vsel = polyop.getVertSelection obj as array
if vsel.Count == 0 do return false
--
sort vsel
for j = vsel.count to 1 by -1 do (
pt = polyop.getVert obj vsel[j]
for i = polyop.getNumVerts obj to 1 by -1 where (d = distance pt (pt2 = polyop.getVert obj i)) <= threshold do
( if i != vsel[j] do (
format "welding.. % and %
" i vsel[j]
polyop.weldVerts obj vsel[j] i pt2
)
)
)
)
format "event: %
" ev
format "%
" nodes
)
if isKindOf callback Value do
(
-- callback.Enabled = false -- what is this .Enable for?
callback = undefined
gc light:true
format "callback reset
"
)
callback = NodeEventCallback mouseUp:true geometryChanged:OnGeometryChanged
)
)
) --end cb01
)--end rollout
createdialog autowelder 200 50
It is better to create NodeEventCallback on rollout open and destroy it on rollout close. Now you destroy it and recreate each time cb01 is toggled.
try(destroydialog ::autowelder)catch()
rollout autowelder ""
(
local callback
checkbox cb01 "Auto-weld"
slider sld01 "" pos:(cb01.pos+[110,0]) type:#float ticks:0 width:80 range:[0.1,5,1]
edittext txt01 "" pos:(cb01.pos +[68,0]) width:35 text:(sld01.value as string)
fn OnGeometryChanged ev nodes =
(
if subObjectLevel != 1 or ev != #geometryChanged or cb01.checked == false do return false
local obj = getAnimByHandle nodes[1]
local threshold = sld01.value
if classof obj == Editable_Poly do (
local vsel = polyop.getVertSelection obj as array
if vsel.Count == 0 do return false
sort vsel
for j = vsel.count to 1 by -1 do (
pt = polyop.getVert obj vsel[j]
for i = polyop.getNumVerts obj to 1 by -1 where (d = distance pt (pt2 = polyop.getVert obj i)) <= threshold do (
if i != vsel[j] do (
format "welding.. % and %
" i vsel[j]
polyop.weldVerts obj vsel[j] i pt2
)
)
)
)
)
on sld01 changed state do ( txt01.text = (sld01.value as string) )
on txt01 changed state do ( sld01.value = (txt01.text as float) )
on cb01 changed state do (
if isProperty callback #Enabled then (
callback.Enabled = state
) else cb01.checked = false
)
on autowelder open do (
if isKindOf callback Value do
(
try (callback.Enabled = false ) catch()
callback = undefined
gc light:true
)
callback = NodeEventCallback enabled:false mouseUp:true geometryChanged:OnGeometryChanged
)
on autowelder close do (
if isKindOf callback Value do
(
try (callback.Enabled = false ) catch()
callback = undefined
gc light:true
format "callback destroyed
"
)
)
)
createdialog autowelder 200 50