I can't help you, sorry. I've always just deleted the parts of a model that I wanted to mirror, then unwrapped, then mirrored those parts again and made sure I never had to do symmetric editing afterwards. There might be a way to do it in Max, but I always assumed there wasn't. Then again, I'm still on Max 7, heh.
If it's only a small edit, I wouldn't mind doing it for you in Silo. If it's anything more than that, I hope someone knows of a way to do it in Max. Which version are you on?
You could try this: duplicate the model, edit using Symmetry, then copy the Unwrap modifier from the original object's stack to the new object. Dunno if it'll work but it might be worth a try.
I coulda sworn bobo had a script to do this or something... just mirror your transformations along an axis and find a threshold of the position to find what points to modify on the other side...
Anyway, thanks for the link
that modifier looks pretty robust
--globale
qazxsw2_symmetry_undo = "MySim"
qazxsw2_symmetry_auto_axa = undefined
struct sym_vert
(
index,
simetric
)
fn baga_index_de_mesa_scoate_index_de_uv mesa index canal =
(
vertecsi_de_pe_fete =#()
fete_cu_vertexu = (polyop.GetFacesUsingVert mesa index)
unde_pe_fete_cu_vertexu =#()
indecsi_mapare = #()
rezultat = #()
for f in fete_cu_vertexu do
(
append vertecsi_de_pe_fete (polyOp.getFaceVerts mesa f)
)
for v_f in vertecsi_de_pe_fete do
(
for d = 1 to v_f.Count do
(
if v_f[d] == index do
(
append unde_pe_fete_cu_vertexu d
)
)
)
for f_map in fete_cu_vertexu do
(
append indecsi_mapare (polyop.getMapFace mesa canal f_map)
)
for i_map = 1 to unde_pe_fete_cu_vertexu.Count do
(
append rezultat indecsi_mapare[i_map][(unde_pe_fete_cu_vertexu[i_map])]
)
return rezultat
)
fn gaseste_invers mesa v_index val_x val_y val_z =
(
distanta_test = 99999999999999999999999
ala_bun = v_index
mat_i = (matrix3 [val_x,0,0] [0,val_y,0] [0,0,val_z] [0,0,0])
pozitia_pe_invers = ((((polyop.GetVert mesa.baseobject v_index node:mesa)*inverse mesa.transform)*mat_i)*mesa.transform)
for vert = 1 to (polyop.GetNumVerts mesa) do
(
dist_nou = (distance pozitia_pe_invers ((polyop.GetVert mesa.baseobject vert node:mesa)))
if dist_nou < distanta_test do
(
distanta_test = dist_nou
ala_bun = vert
)
)
return ala_bun
)
fn precalculare_simetrie mesa val_x val_y val_z =
(
undo off
(
cati_verti = (polyop.GetNumVerts mesa)
progres_l = cati_verti/100
if progres_l < 1 do progres_l = 1
--print "sss"
--print progres_l
--print "sss"
progres = 1
sstring = "Searching Symmetry: "
if val_x == -1 do sstring +="X"
if val_y == -1 do sstring +="Y"
if val_z == -1 do sstring +="Z"
progressStart sstring
buffer_sym = #()
for vt = 1 to cati_verti do
(
progres = (vt/progres_l)-progres_l
if progres < 0 do progres = 0
if (progressUpdate (progres as integer)) then
(
sym_vert_temp = sym_vert (vt) (gaseste_invers mesa vt val_x val_y val_z)
append buffer_sym sym_vert_temp
)
else
(
vt = cati_verti
progressEnd()
return undefined
)
)
)
progressEnd()
return buffer_sym
)
--print (precalculare_simetrie selection[1] 1 -1 1)
fn transforma_dupa_sym_buffer buffer_sym mesa vert val_x val_y val_z cu_mapare =
(
mat_inv = (matrix3 [val_x,0,0] [0,val_y,0] [0,0,val_z] [0,0,0])
for m = 1 to buffer_sym.Count do
(
if buffer_sym[m].index == vert and buffer_sym[m].index != buffer_sym[m].simetric do
(
o_nou = ((polyop.GetVert mesa.baseobject buffer_sym[m].index node:mesa)*inverse mesa.transform)
poz_fi = (o_nou * mat_inv)
--print poz_fi
polyOP.SetVert mesa.baseobject (buffer_sym[m].simetric) poz_fi
--pentru_uvu
canalu = polyOp.getNumMaps mesa.baseobject
if canalu > 0 and cu_mapare do
(
for j = 0 to (canalu-1) do
(
if (polyOp.getMapSupport mesa.baseobject j) and ((polyOp.getNumMapVerts mesa.baseobject j) > 0) do
(
index_normal = baga_index_de_mesa_scoate_index_de_uv mesa.baseobject buffer_sym[m].index j
index_oglinda = baga_index_de_mesa_scoate_index_de_uv mesa.baseobject buffer_sym[m].simetric j
for i_nor = 1 to index_normal.Count do
(
try
(
temp_poz = polyOp.getMapVert mesa.baseobject j index_normal[i_nor]
polyOp.setMapVert mesa.baseobject j index_oglinda[i_nor] temp_poz
)
catch()
)
)
)
)
)
)
)
fn simetrie_selectie_sym_buffer buffer_sym mesa val_x val_y val_z cu_mapare =
(
undo qazxsw2_symmetry_undo on
(
verti_selectati = (polyOP.getVertSelection mesa as array)
for vs in verti_selectati do
(
transforma_dupa_sym_buffer buffer_sym mesa vs val_x val_y val_z cu_mapare
)
)
)
fn gaseste_axa_simetrie_f1 mesa =
(
buf_x = (precalculare_simetrie selection[1] -1 1 1)
buf_y = (precalculare_simetrie selection[1] 1 -1 1)
buf_z = (precalculare_simetrie selection[1] 1 1 -1)
px_r = 0
px = 0
py = 0
pz = 0
for bx = 1 to buf_x.Count do
(
px_r += buf_x[bx].index
)
for b_x = 1 to buf_x.Count do
(
px += buf_x[b_x].simetric
)
---
for b_y = 1 to buf_y.Count do
(
py += buf_y[b_y].simetric
)
---
for b_z = 1 to buf_z.Count do
(
pz += buf_z[b_z].simetric
)
--print px
--print py
--print pz
--print px_r
-----------------------
if px/10000 == px_r/10000 do
(
--print "x"
qazxsw2_symmetry_auto_axa = "x"
return buf_x
)
if py/10000 == px_r/10000 do
(
--print "y"
qazxsw2_symmetry_auto_axa = "y"
return buf_y
)
if pz/10000 == px_r/10000 do
(
--print "z"
qazxsw2_symmetry_auto_axa = "z"
return buf_z
)
return undefined
)
fn cu_axa_pe_x mesa =
(
buf_x = (precalculare_simetrie selection[1] -1 1 1)
return buf_x
)
fn cu_axa_pe_y mesa =
(
buf_y = (precalculare_simetrie selection[1] 1 -1 1)
return buf_y
)
fn cu_axa_pe_z mesa =
(
buf_z = (precalculare_simetrie selection[1] 1 1 -1)
return buf_z
)
--print (gaseste_axa_simetrie_f1 $)--auto_sim
----------------------
--cu_axa_pe_y mesa
--cu_axa_pe_z mesa
--cu_axa_pe_x mesa
----------------------
--transforma_dupa_sym_buffer buf_demo selection[1] 259 -1 1 1
--buf_demo = (precalculare_simetrie selection[1] -1 1 1)
--print buf_demo
--simetrie_selectie_sym_buffer buf_demo selection[1] -1 1 1
-------------------------------------------------------------
--globale
if qazxsw2_symmetry_sim_y == undefined do qazxsw2_symmetry_sim_y = #()
if qazxsw2_symmetry_sim_z == undefined do qazxsw2_symmetry_sim_z = #()
if qazxsw2_symmetry_sim_x == undefined do qazxsw2_symmetry_sim_x = #()
fn save_sim =
(
unde = getsavefilename types:"*.sim_dat|*.sdat"
if (unde != undefined) and (unde != "") do
(
intrare_f = createfile unde
if intrare_f != undefined do
(
format "%" "Fisier de simetrie KIKI n" to:intrare_f
for sx in qazxsw2_symmetry_sim_x do
(
format "%,%n" sx.index sx.simetric to:intrare_f
)
format "%" "|n" to:intrare_f
for sy in qazxsw2_symmetry_sim_y do
(
format "%,%n" sy.index sy.simetric to:intrare_f
)
format "%" "|n" to:intrare_f
for sz in qazxsw2_symmetry_sim_z do
(
format "%,%n" sz.index sz.simetric to:intrare_f
)
)
)
)
fn transforma_string_sym_vert intrare =
(
int2 = filterString intrare ","
if (int2[1] != undefined) and (int2[2] != undefined) do
(
sret = sym_vert (int2[1] as integer) (int2[2] as integer)
return sret
)
return undefined
)
fn load_sim =
(
temp_i = #()
intrari = #()
temp_x = #()
temp_y = #()
temp_z = #()
dat_x = #()
dat_y = #()
dat_z = #()
unde = getOpenFileName types:"*.sim_dat|*.sdat"
if (unde != undefined) do
(
intrare_f = openFile unde
if intrare_f != undefined do
(
while not(eof intrare_f) do
(
append temp_i (readLine intrare_f)
)
)
close intrare_f
)
if temp_i != undefined do
(
--pentru index de intrare
for i = 1 to temp_i.Count do
(
if temp_i[i] == "|" or temp_i[i] == "Fisier de simetrie KIKI " do
(
append intrari (i+1)
)
)
--pentru_x
for j = intrari[1]+1 to (intrari[2]) do
(
(
append temp_x temp_i[j]
)
)
--pentru_y
for j = intrari[2] to ((intrari[3])-2) do
(
(
append temp_y temp_i[j]
)
)
--pentru_z
for k = intrari[3] to ((temp_i.Count)) do
(
(
append temp_z temp_i[k]
)
)
-----------------
--transfera in date
for m = 1 to temp_x.Count do
(
if temp_x[m] != undefined do
(
--print "s"
x_tm = (transforma_string_sym_vert temp_x[m])
if x_tm != undefined do
(
append dat_x x_tm
)
)
)
for n = 1 to temp_y.Count do
(
if temp_y[n] != undefined do
(
--print "s2"
y_tm = (transforma_string_sym_vert temp_y[n])
if y_tm != undefined do
(
append dat_y y_tm
)
)
)
for p = 1 to temp_z.Count do
(
if temp_z[p] != undefined do
(
--print "s3"
z_tm = (transforma_string_sym_vert temp_z[p])
if z_tm != undefined do
(
--print z_tm
append dat_z z_tm
)
)
)
)
qazxsw2_symmetry_sim_x = dat_x
qazxsw2_symmetry_sim_y = dat_y
qazxsw2_symmetry_sim_z = dat_z
)
rollout symmRollout "Move Symmetry" width:162 height:498
(
button auto_sim "Auto find Symmetry" pos:[15,256] width:134 height:28
button btn_x "X Symmetry" pos:[15,289] width:134 height:28
button btn_y "Y Symmetry" pos:[15,321] width:134 height:28
button btn_z "Z Symmetry" pos:[15,354] width:134 height:28
GroupBox grp1 "Activ Buffer" pos:[14,6] width:133 height:49
label lbl_x " " pos:[23,26] width:38 height:24
label lbl_y " " pos:[64,26] width:36 height:24
label lbl_z " " pos:[109,26] width:35 height:24
button ok_s_x "Call on selection Symmetry X" pos:[10,63] width:141 height:26
button btn16 "Call on selection Symmetry Y" pos:[10,94] width:141 height:26
button btn17 "Call on selection Symmetry Z" pos:[10,126] width:141 height:26
label lbl10 " Popescu Alexandru Cristian nr kiki_karon@yahoo.com" pos:[6,458] width:150 height:30
button btn_k "Load" pos:[13,386] width:136 height:25
button btn_s "Save" pos:[13,416] width:135 height:26
checkbox cb1 "Keep UVW" pos:[10,156] width:135 height:16 checked:true
Groupbox grp2 "Symmetry buffer" pos:[7,239] width:148 height:212
checkbutton rtx "Real Time X Symmetry" pos:[11,176] width:139 height:18 enabled:false
checkbutton rty "Real Time Y Symmetry" pos:[11,197] width:139 height:18 enabled:false
checkbutton rtz "Real Time Z Symmetry" pos:[11,218] width:139 height:18 enabled:false
on symmRollout open do
(
if qazxsw2_symmetry_sim_y.Count != 0 do lbl_y.text = " Y n" + (qazxsw2_symmetry_sim_y.Count as string)
if qazxsw2_symmetry_sim_x.Count != 0 do lbl_x.text = " X n" + (qazxsw2_symmetry_sim_x.Count as string)
if qazxsw2_symmetry_sim_z.Count != 0 do lbl_z.text = " Z n" + (qazxsw2_symmetry_sim_z.Count as string)
-----
if qazxsw2_symmetry_sim_y.Count != 0 do rty.enabled = true
if qazxsw2_symmetry_sim_x.Count != 0 do rtx.enabled = true
if qazxsw2_symmetry_sim_z.Count != 0 do rtz.enabled = true
)
on rtx changed state do
(
if state == on do
(
when geometry selection[1].baseobject changes id:#smart_sim_rt_x do
(
if selection[1] != undefined and ((classof selection[1].baseobject) == Editable_poly) do
(
simetrie_selectie_sym_buffer qazxsw2_symmetry_sim_x selection[1] -1 1 1 cb1.State
)
)
)
if state != on do
(
deleteallChangeHandlers id:#smart_sim_rt_x
)
)
on rty changed state do
(
if state == on do
(
when geometry selection[1].baseobject changes id:#smart_sim_rt_y do
(
if selection[1] != undefined and ((classof selection[1].baseobject) == Editable_poly) do
(
simetrie_selectie_sym_buffer qazxsw2_symmetry_sim_y selection[1] 1 -1 1 cb1.State
)
)
)
if state != on do
(
deleteallChangeHandlers id:#smart_sim_rt_y
)
)
on rtz changed state do
(
if state == on do
(
when geometry selection[1].baseobject changes id:#smart_sim_rt_z do
(
if selection[1] != undefined and ((classof selection[1].baseobject) == Editable_poly) do
(
simetrie_selectie_sym_buffer qazxsw2_symmetry_sim_z selection[1] 1 1 -1 cb1.State
)
)
)
if state != on do
(
deleteallChangeHandlers id:#smart_sim_rt_z
)
)
on auto_sim pressed do
(
if (classof selection[1].baseobject) == Editable_poly do
(
temp_lib = gaseste_axa_simetrie_f1 selection[1]
if qazxsw2_symmetry_auto_axa != undefined do
(
if qazxsw2_symmetry_auto_axa == "x" do
(
qazxsw2_symmetry_sim_x = temp_lib
)
if qazxsw2_symmetry_auto_axa == "y" do
(
qazxsw2_symmetry_sim_y = temp_lib
)
if qazxsw2_symmetry_auto_axa == "z" do
(
qazxsw2_symmetry_sim_z = temp_lib
)
)
qazxsw2_symmetry_auto_axa = undefined
if qazxsw2_symmetry_sim_y.Count != 0 do lbl_y.text = " Y n" + (qazxsw2_symmetry_sim_y.Count as string)
if qazxsw2_symmetry_sim_x.Count != 0 do lbl_x.text = " X n" + (qazxsw2_symmetry_sim_x.Count as string)
if qazxsw2_symmetry_sim_z.Count != 0 do lbl_z.text = " Z n" + (qazxsw2_symmetry_sim_z.Count as string)
-----
if qazxsw2_symmetry_sim_y.Count != 0 do rty.enabled = true
if qazxsw2_symmetry_sim_x.Count != 0 do rtx.enabled = true
if qazxsw2_symmetry_sim_z.Count != 0 do rtz.enabled = true
)
)
on btn_x pressed do
(
if (classof selection[1].baseobject) == Editable_poly do
(
qazxsw2_symmetry_sim_x = cu_axa_pe_x selection[1]
if qazxsw2_symmetry_sim_x.Count != 0 do lbl_x.text = " X n" + (qazxsw2_symmetry_sim_x.Count as string)
if qazxsw2_symmetry_sim_x.Count != 0 do rtx.enabled = true
)
)
on btn_y pressed do
(
if (classof selection[1].baseobject) == Editable_poly do
(
qazxsw2_symmetry_sim_y = cu_axa_pe_y selection[1]
if qazxsw2_symmetry_sim_y.Count != 0 do lbl_y.text = " Y n" + (qazxsw2_symmetry_sim_y.Count as string)
if qazxsw2_symmetry_sim_y.Count != 0 do rty.enabled = true
)
)
on btn_z pressed do
(
if (classof selection[1].baseobject) == Editable_poly do
(
qazxsw2_symmetry_sim_z = cu_axa_pe_z selection[1]
if qazxsw2_symmetry_sim_z.Count != 0 do lbl_z.text = " Z n" + (qazxsw2_symmetry_sim_z.Count as string)
if qazxsw2_symmetry_sim_z.Count != 0 do rtz.enabled = true
)
)
on ok_s_x pressed do
(
if selection[1] != undefined and ((classof selection[1].baseobject) == Editable_poly) do
(
simetrie_selectie_sym_buffer qazxsw2_symmetry_sim_x selection[1] -1 1 1 cb1.State
)
)
on btn16 pressed do
(
if selection[1] != undefined and ((classof selection[1].baseobject) == Editable_poly) do
(
simetrie_selectie_sym_buffer qazxsw2_symmetry_sim_y selection[1] 1 -1 1 cb1.State
)
)
on btn17 pressed do
(
if selection[1] != undefined and ((classof selection[1].baseobject) == Editable_poly) do
(
simetrie_selectie_sym_buffer qazxsw2_symmetry_sim_z selection[1] 1 1 -1 cb1.State
)
)
on btn_k pressed do
(
load_sim()
if qazxsw2_symmetry_sim_y.Count != 0 do lbl_y.text = " Y n" + (qazxsw2_symmetry_sim_y.Count as string)
if qazxsw2_symmetry_sim_x.Count != 0 do lbl_x.text = " X n" + (qazxsw2_symmetry_sim_x.Count as string)
if qazxsw2_symmetry_sim_z.Count != 0 do lbl_z.text = " Z n" + (qazxsw2_symmetry_sim_z.Count as string)
)
on btn_s pressed do
(
save_sim()
)
)createdialog symmRollout
--save_sim()
--load_sim buffer_x buffer_y buffer_z
OK, this is a BETA script , it calculates symmetry using the pivot as the mirror point, the mesh should be an 'editable poly' and it should have =< 10000 tris
You should 'Reset Xform' the mesh before using it,you should not have any modifiers in the stack,
It only works on move,rotate,scale.
It can't use soft-selection.
To use it press the :
-Symmetry buffer>X Symmetry(or what kind of symmetry you need).
-Wait to male the buffer(on my computer for 10000tris took 3min).
-press the Real Time X Symmetry and work.
-you can also press 'Call on selection Symmetry X'(or what kind of symmetry you need) if you don't need it to be real time or it drags to much,select what you want to be mirrored and press it.
-if you want to keep the buffer you can save it and use it later(Symmetry buffer>Save\Load).
Replies
If it's only a small edit, I wouldn't mind doing it for you in Silo. If it's anything more than that, I hope someone knows of a way to do it in Max. Which version are you on?
polyboost should be able to do what you need
I should look in to polyboost...
http://rpmanager.com/plugins/Transmographier.htm
I coulda sworn bobo had a script to do this or something... just mirror your transformations along an axis and find a threshold of the position to find what points to modify on the other side...
Anyway, thanks for the link
that modifier looks pretty robust
OK, this is a BETA script , it calculates symmetry using the pivot as the mirror point, the mesh should be an 'editable poly' and it should have =< 10000 tris
You should 'Reset Xform' the mesh before using it,you should not have any modifiers in the stack,
It only works on move,rotate,scale.
It can't use soft-selection.
To use it press the :
-Symmetry buffer>X Symmetry(or what kind of symmetry you need).
-Wait to male the buffer(on my computer for 10000tris took 3min).
-press the Real Time X Symmetry and work.
-you can also press 'Call on selection Symmetry X'(or what kind of symmetry you need) if you don't need it to be real time or it drags to much,select what you want to be mirrored and press it.
-if you want to keep the buffer you can save it and use it later(Symmetry buffer>Save\Load).