Retopology from the UV mesh


#1

i was reading this thread and i got an idea.
http://forums.cgsociety.org/showthread.php?f=6&t=1152752

what if we used the projection modifier to project a flattened mesh onto a 3d mesh.

Marvelous Designer uses triangulated meshes. when you import that mesh you can not use it in zbrush mudbox and render with displacement. what you get is the mesh and of course the UV’s. the UV 's are created from the patterns in MD. automatic retopology is good but not good enough because you have to do a lot of manual work around the mesh

so i was thinking :
-export model from Marvelous Designer. model has UV’s
-flatten the model and create it based on the UV’s. this script does this
http://www.scriptspot.com/3ds-max/scripts/uv-2-mesh
-retopology on top of the flattened mesh. your edge flow will be perfect because it will be based on the flattened pattern
-UV the retopo mesh so that its in the same position as the original MD mesh. in the UVW modifier.
-project the retopologized mesh on the original marvelous designer model with the projection modifier. use the flattened mesh as a guide .

the script would need the information from the mesh channels and UV channels?
-position of the retopo model on top of the flattened model. the position of the vertex on top of the faces of the flattened model and than project the same position on the original model. with the raycast.



Marvelous Designer Retopology
#2

i found those videos for maya. transfer attributes.

if two objects with different topologyy have the same uv’s we can we project a mesh to another mesh?

http://www.youtube.com/watch?v=B7ZwPjCubs0
http://www.youtube.com/watch?v=ZMuw0sfMKQs
http://thomasmansencal.com/Sharing/Videos/Match_Topology_Through_UVs.swf


#3

Yep. This is awesome option in maya. Very useful. We can only hope to see this in max2015,
because this is not easy task to achive with mxs.


#4

Inspired by first tutorial I wrote simple workaround way to achive similar result.
First thing first > example scene

masterObj = Rectangle name:"Master001" length:100 width:100 pos:[0,50,50] dir:-y_axis wirecolor:green
addmodifier masterObj (Garment_Maker density:0.2)
flatObj = copy masterObj ; flatObj.pos.y = -50 ; flatObj.name = "flat001" ; flatObj.wirecolor = blue
addModifier masterObj (Noisemodifier seed:10 scale:40 strength:[0,0,50])
addModifier masterObj (Bend angle:180 BendAxis:0)


#5
(
try(destroyDialog ::bgaRoll)catch()
rollout bgaRoll "MarvelousTool"
(
	local master, flat, newObj
	fn filterGeo obj = isKindOf obj GeometryClass and canConvertTo obj Editable_Mesh
	pickbutton pb_master "Pick Master Object" pos:[5,5] width:140 filter:filterGeo
	pickbutton pb_flat "Pick Flat Object" pos:[5,30] width:140 filter:filterGeo
	button btn_do "Do the Job!" pos:[5,55] width:140
	spinner spn_quad "Quad Size[%]: " pos:[5,80] fieldwidth:55 range:[.1,1e2,4]
	spinner spn_warp "Warp Offset:   " pos:[6,100] fieldwidth:55 range:[.001,1e2,.001]
	label lbl "	  *** Morph Object ***" pos:[5,120] width:140 height:16 style_sunkenedge:on
	slider sl_morph "" pos:[10,140] width:140 ticks:0
	
	on pb_master picked obj do (if isValidNode obj do (master = obj ; pb_master.text = master.name))
	on pb_flat picked obj do (if isValidNode obj do (flat = obj ; pb_flat.text = flat.name))
	on btn_do pressed do
	(
		if isValidNode master and isValidNode flat do
		(
			max modify mode
			with redraw off
			(
				newObj = copy flat ; newObj.name = (flat.name+"_clone")
				addModifier newObj (Quadify_Mesh name:"Quadify" quadsize:spn_quad.value)
				addModifier newObj (Skin_Wrap name:"Warpy" engine:0 falloff:spn_warp.value meshList:#(flat))
				addModifier flat (Morpher()) ; modPanel.setCurrentObject flat.modifiers["Morpher"]
				WM3_MC_BuildFromNode flat.modifiers["Morpher"] 1 master
			)
		)
	)
	on spn_quad buttonDown do if isValidNode newObj do flagForeground newObj on
	on spn_quad buttonDown do if isValidNode newObj do flagForeground newObj off
	on spn_quad changed val do if isValidNode newObj do
	(
		if (qMody = newObj.modifiers["Quadify"]) != null do qMody.quadsize = val
	)
	on spn_warp buttonDown do if isValidNode newObj do flagForeground newObj on
	on spn_warp buttonDown do if isValidNode newObj do flagForeground newObj off
	on spn_warp changed val do if isValidNode newObj do
	(
		if (wMody = newObj.modifiers["Warpy"]) != null do wMody.offset = val
	)
	on sl_morph buttonDown do if isValidNode flat do flagForeground flat on
	on sl_morph buttonDown do if isValidNode flat do flagForeground flat off
	on sl_morph changed val do if isValidNode flat do
	(
		if (mMody = flat.modifiers["Morpher"]) != null do WM3_MC_SetValue mMody 1 val
	)
)
createDialog bgaRoll 150 180 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow) ; ok
)

#6

Run this tool , pick master and flat object. Leave default value for the spinners. Press “Do the Job!” button. This will create new optimized (quadrified) object. Drag the slider to see morphing.
Also U can set quad size affter creation. If your mesh is heavy before you press “Do …” button set value to 8-10%.

Edit:
Maybe someone have better solution … Anyway … Who sad that max can’t to this :slight_smile:
Maya have better implementation of this approch but max have “MODIFIERS”
and non-destructive way. :cool:


#7
(
 try(destroyDialog ::bgaRoll)catch()
 rollout bgaRoll "MarvelousTool b1"
 (
 	local master, flat, newObj, mat
 	local checkboard = standard name:"PreviewMat" diffuseMap:(checker name:"checkboard") showinviewport:on
 	fn filterGeo obj = isKindOf obj GeometryClass and canConvertTo obj Editable_Mesh
 	label lbl1 "				S E T U P" pos:[5,5] width:140 height:16 style_sunkenedge:on	
 	pickbutton pb_master "Pick Master Object" pos:[5,25] width:140 filter:filterGeo
 	pickbutton pb_flat "Pick Flat Object" pos:[5,50] width:140 filter:filterGeo
 	button btn_do "Do the Job!" pos:[5,75] width:140
 	spinner spn_quad "Quad Size[%]: " pos:[5,100] fieldwidth:55 range:[.1,1e2,4] scale:1e-2
 	spinner spn_warp "Warp Offset:   " pos:[6,120] fieldwidth:55 range:[.001,1e2,.001]
 	label lbl2 "			   M O R P H" pos:[5,140] width:140 height:16 style_sunkenedge:on
 	slider sl_morph "" pos:[11,160] width:140 ticks:0
 	label lbl3 "		   P R E V I E W" pos:[5,188] width:140 height:16 style_sunkenedge:on
 	spinner spn_size "Checker Size:   " pos:[5,208] fieldwidth:55 range:[.01,1e3,5]	
 	checkbutton cbtn_mat "Checker Preview" pos:[5,228] width:140 highlightColor:[50,50,50]
 	
 	on pb_master picked obj do (if isValidNode obj do (master = obj ; pb_master.text = master.name))
 	on pb_flat picked obj do (if isValidNode obj do (flat = obj ; mat = obj.mat ; pb_flat.text = flat.name))
 	on btn_do pressed do
 	(
 		if isValidNode master and isValidNode flat do
 		(
 			if flat.modifiers.count > 0 and flat.modifiers[1].name == "Morphy" do deletemodifier flat 1
 			if isValidNode newObj do delete newObj ; max modify mode
 			newObj = copy flat ; newObj.name = (flat.name+"_clone")
 			addModifier newObj (Quadify_Mesh name:"Quadify" quadsize:spn_quad.value)
 			addModifier newObj (Skin_Wrap name:"Wrapy" engine:0 falloff:spn_warp.value meshList:#(flat))
 			addModifier flat (Morpher name:"Morphy") ; modPanel.setCurrentObject flat.modifiers["Morphy"]
 			WM3_MC_BuildFromNode flat.modifiers["Morphy"] 1 master ; flat.xray = on ; select newObj
 		)
 	)
 	on spn_quad buttonDown do if isValidNode newObj do 
 	(
 		sl_morph.value = 0 
 		WM3_MC_SetValue flat.modifiers["Morphy"] 1 0.0
 		newObj.modifiers["Wrapy"].enabled = off
 		flagForeground newObj on
 	)
 	on spn_quad buttonUp do if isValidNode newObj do 
 	(
 		newObj.modifiers["Wrapy"].enabled = on
 		newObj.modifiers["Wrapy"].reset()
 		flagForeground newObj off
 	)
 	on spn_quad changed val do if isValidNode newObj do
 	(
 		if (qMody = newObj.modifiers["Quadify"]) != null do qMody.quadsize = val
 	)
 	on spn_warp buttonDown do if isValidNode newObj do flagForeground newObj on
 	on spn_warp buttonUp do if isValidNode newObj do flagForeground newObj off
 	on spn_warp changed val do if isValidNode newObj do
 	(
 		if (wMody = newObj.modifiers["Wrapy"]) != null do wMody.offset = val
 	)
 	on sl_morph buttonDown do if isValidNode flat do flagForeground flat on
 	on sl_morph buttonUp do if isValidNode flat do flagForeground flat off
 	on sl_morph changed val do if isValidNode flat do
 	(
 		if (mMody = flat.modifiers["Morphy"]) != null do WM3_MC_SetValue mMody 1 val
 	)
 	on cbtn_mat changed state do if isValidNode newObj do
 	(
 		if not state then newObj.mat = mat else
 		(
 			checkboard.diffusemap.coords.U_Tiling = checkboard.diffusemap.coords.V_Tiling = spn_size.value
 			newObj.mat = checkboard
 		)
 	)
 	on spn_size changed val do if isValidNode newObj and cbtn_mat.checked do
 	(
 		checkboard.diffusemap.coords.U_Tiling = checkboard.diffusemap.coords.V_Tiling = val
 	)	
 )
 createDialog bgaRoll 150 250 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow) ; ok
 )
 

#8

wow. this works very good. its going in the right direction.

to bad that Joel Mongeon can not share his script
http://www.joelmongeon.com/Whitepage.html
‘’ My script then does a raycast from each vertex onto the 2D mesh to find the appropriate face that it sits upon. The tool then generates a copy of the retopologized mesh and snaps each vertex to the face of the original 3D cloth.’’
‘‘If you are interested in retopologizing inside of 3ds max in a similar fashion as the script, take a look at 3ds max’s mesh and uv channels, and the projection modifier in the help menu.’’

raycast
projection modifier
mesh and uv channel


#9

i tryed now how to use this script with a custom quad mesh. a mesh that you create yourself.

i retopoligized the mesh on top of the flattened triangulated mesh. run script. than i copied wrapy (skin wrap) to my own repologized mesh. and it got very close.



#10

Added option to chose between “auto retopologizing mode” (as first update) or to
pick custom retopologized flatened object.
BTW I not have time to test this update. Tell me if you have some problem with it.

(
try(destroyDialog ::bgaRoll)catch()
rollout bgaRoll "MarvelousTool b2"
(
	local master, flat, newObj, mat
	local checkboard = standard name:"PreviewMat" diffuseMap:(checker name:"checkboard") showinviewport:on
	fn filterGeo obj = isKindOf obj GeometryClass and canConvertTo obj Editable_Mesh
	label lbl1 "				S E T U P" pos:[5,5] width:140 height:16 style_sunkenedge:on	
	pickbutton pb_master "Pick Master Object" pos:[5,25] width:140 filter:filterGeo
	pickbutton pb_flat "Pick Flat Object" pos:[5,50] width:140 filter:filterGeo
	checkbox cb_auto "Auto Retopology Mode" pos:[5,75] width:140 checked:on
	spinner spn_quad "Quad Size[%]: " pos:[5,95] fieldwidth:55 range:[.1,1e2,4] scale:1e-2
	pickbutton pb_retopo "Pick Retopologized Object" pos:[5,115] width:140 enabled:off filter:filterGeo 
	spinner spn_warp "Warp Offset:   " pos:[6,140] fieldwidth:55 range:[.001,1e2,.001]
	button btn_do "Do the Job!" pos:[5,160] width:140
	label lbl2 "			   M O R P H" pos:[5,185] width:140 height:16 style_sunkenedge:on
	slider sl_morph "" pos:[11,205] width:140 ticks:0
	label lbl3 "		   P R E V I E W" pos:[5,233] width:140 height:16 style_sunkenedge:on
	spinner spn_size "Checker Size:   " pos:[5,253] fieldwidth:55 range:[.01,1e3,5]	
	checkbutton cbtn_mat "Checker Preview" pos:[5,273] width:140 highlightColor:[50,50,50]
	
	on cb_auto changed state do
	(
		spn_quad.enabled = state
		pb_retopo.enabled = not state
	)
	on pb_master picked obj do (if isValidNode obj do (master = obj ; pb_master.text = master.name))
	on pb_flat picked obj do 
	(
		if isValidNode obj do 
		(
			flat = obj ; mat = obj.mat ; pb_flat.text = flat.name
			if isValidNode newObj do newObj.center = flat.center
		)
	)
	on pb_retopo picked obj do 
	(
		if isValidNode obj do 
		(
			newObj = obj ; pb_master.text = newObj.name
			if isValidNode flat do newObj.center = flat.center
		)
	)
	on btn_do pressed do
	(
		if isValidNode master and isValidNode flat do
		(
			sl_morph.value = 0
			if (mMody = flat.modifiers["Morphy"]) != null do WM3_MC_SetValue mMody 1 0.0
			if flat.modifiers.count > 0 and flat.modifiers[1].name == "Morphy" do deletemodifier flat 1
			if isValidNode newObj and cb_auto.checked == true do (delete newObj ; newObj = null)	
			max modify mode	
			if cb_auto.checked do
			(
				newObj = copy flat ; newObj.name = (flat.name+"_clone")
				addModifier newObj (Quadify_Mesh name:"Quadify" quadsize:spn_quad.value)
			)
			if not isValidNode newObj then messageBox "You forgot to pick Retopologized Object" title:"Warning" beep:off else
			(
				addModifier newObj (Skin_Wrap name:"Wrapy" engine:0 falloff:spn_warp.value meshList:#(flat))
				addModifier flat (Morpher name:"Morphy") ; modPanel.setCurrentObject flat.modifiers["Morphy"]
				WM3_MC_BuildFromNode flat.modifiers["Morphy"] 1 master ; flat.xray = on ; select newObj
			)
		)
	)
	on spn_quad buttonDown do if isValidNode newObj do 
	(
		sl_morph.value = 0 
		WM3_MC_SetValue flat.modifiers["Morphy"] 1 0.0
		newObj.modifiers["Wrapy"].enabled = off
		flagForeground newObj on
	)
	on spn_quad buttonUp do if isValidNode newObj do 
	(
		newObj.modifiers["Wrapy"].enabled = on
		newObj.modifiers["Wrapy"].reset()
		flagForeground newObj off
	)
	on spn_quad changed val do if isValidNode newObj do
	(
		if (qMody = newObj.modifiers["Quadify"]) != null do qMody.quadsize = val
	)
	on spn_warp buttonDown do if isValidNode newObj do flagForeground newObj on
	on spn_warp buttonUp do if isValidNode newObj do flagForeground newObj off
	on spn_warp changed val do if isValidNode newObj do
	(
		if (wMody = newObj.modifiers["Wrapy"]) != null do wMody.offset = val
	)
	on sl_morph buttonDown do if isValidNode flat do flagForeground flat on
	on sl_morph buttonUp do if isValidNode flat do flagForeground flat off
	on sl_morph changed val do if isValidNode flat do
	(
		if (mMody = flat.modifiers["Morphy"]) != null do WM3_MC_SetValue mMody 1 val
	)
	on cbtn_mat changed state do if isValidNode newObj do
	(
		if not state then newObj.mat = mat else
		(
			checkboard.diffusemap.coords.U_Tiling = checkboard.diffusemap.coords.V_Tiling = spn_size.value
			newObj.mat = checkboard
		)
	)
	on spn_size changed val do if isValidNode newObj and cbtn_mat.checked do
	(
		checkboard.diffusemap.coords.U_Tiling = checkboard.diffusemap.coords.V_Tiling = val
	)	
)
createDialog bgaRoll 150 300 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow) ; ok
)

#11

I saw Joel Mongeon blog. Good approch (probably he used max SDK for that).
He also said that Marvelous Designer plans to add “Quadrify” option. Therefore the use of the tool will not be necessary any more.


#12

Marvelous Designer will not add this option. they are lying to their customers to update to the new versions.i think in 2013 they gave an official statement that it doesnt work how they envisioned


#13

I not used till now Skin Wrap motifier. Change parameters and you can tell me what is the best settings.
Latter I can add these also in the script.
U can also continue with MassFx Cloth or default Cloth modifier or use Freeform Conform tools from Ribbon.


#14

Still U can use fantastic Zbrush (ZRemesher) or Mudbox Advanced Retopology solutions. :slight_smile:


#15

Can i ask for a video tutorial about this handy script?
I try it without success maybe i do something wrong…:blush:
Thanks in advance.


#16

First download tool from here.
See how to export models (original and flat) from M.D.
http://www.youtube.com/watch?v=B7ZwPjCubs0
http://www.youtube.com/watch?v=ZMuw0sfMKQs
I don’t have installed Marvelous Designer but you can use code from post #4 as example.
Put this “example” code in Listiner , select whole code and press Shift+Enter.
U will see Master (green) and Flat (blue) object in the scene.
Take a look this Thumbs for more info.


#17

would it be possible so that both the flattened and the retopo mesh are aligned to the marvelous designer mesh? since the retopo mesh has a different topology its hard to move and snap it to the right position.


#18

Try when you imported obj’s (master and flat object) to aligne pivots at the center and then use this tool. If this not help send me some example. I not have M.D. for testing.


#19

i have a test file. its 10mb big. where can i upload it?


#20

Dropbox.com, sendspace.com, 4shared.com, mega.co.nz