Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

MaxScript - SkinWrap not Updating when Required

MaxScript - SkinWrap not Updating when Required

Anonymous
Not applicable
1,276 Views
1 Reply
Message 1 of 2

MaxScript - SkinWrap not Updating when Required

Anonymous
Not applicable

I am trying to automate a procedure I use to copy morphers across slightly different meshes.

 

The steps involve applying a morph modifier with all targets to the previously working mesh. Bring the newer mesh and align in on top of the previous. Ensure all morphers are set to 0, and then apply a Skinwrap with the vertex deformation engine. When incrementing the morph slider on the older mesh, the newer mesh will trace the final position of the vertices as well - I can then collapse the whole stack and use it as a target for the newer mesh.

 

I replicated the whole procedure in a script, but in the end result, the new targets do not deform due to the effects of the skinwrap, I am almost certain it is because the viewport is not refreshed - and hence, the effects of skinwrap are neglected in code.

 

-- The Primary Loop; iterate over all morph targets, duplicate a base mesh,
			-- position it relative to previous base mesh, reset all morph sliders to 0%,
			-- and apply skin wrap. Set the appropriate morph target to 100%, and collapse the
			-- duplicate mesh and set it aside. Repeat for all other morph targets.
			for i = 1 to morphers.count do
			(
				newTarget = copy targetBaseModel
				newTarget.name = morphers[i].name
				
				-- Position the Models on top of each other
				PositionModel newTarget prevBaseModel
				
				morphModifier = prevBaseModel.modifiers["morpher"]
				
				-- Set the Morpher to 0%
				WM3_MC_SetValue morphModifier i 0.0
				
				-- SkinWrap
				skinwrapMod = Skin_Wrap()
				addModifier newTarget skinwrapMod
				skinwrapMod.engine = 1		-- VertexDeformation
				skinwrapMod.falloff = 0.001
				skinwrapMod.distance = 0.001
				skinwrapMod.meshList = append skinwrapMod.meshList(prevBaseModel)
				
				-- Set Morpher to 100%
				WM3_MC_SetValue morphModifier i 100.0

				-- The new target mesh should have the same final shape as the base,
				-- collapse the new target and set it aside
				CollapseStack newTarget
				move newTarget [0,50*i,0]
				
				-- Set the Morpher back to 0% for the next iteration
				WM3_MC_SetValue morphModifier i 0.0
			)
			
			-- Delete the temporary morph modifer
			deleteModifier prevBaseModel 1
		)

Is there a method to ensure the viewport updates the changes before proceeding to the next line of code?

 

Here are the results of the script for context

The setup -- attempting to recreate the 3 morph targets for the "new" meshThe setup -- attempting to recreate the 3 morph targets for the "new" meshThe resulting morph targets appear unchanged from the base model. They must look like the other 3 morph targets if they were skinwrap deformed correctly!The resulting morph targets appear unchanged from the base model. They must look like the other 3 morph targets if they were skinwrap deformed correctly!

0 Likes
1,277 Views
1 Reply
Reply (1)
Message 2 of 2

Anonymous
Not applicable

Alright, an update. I got it to work in some scenarios, but I still do not understand why.

 

First, I surrounded most of the operations I do with the select and completeRedraw function call in an attempt to refresh the viewport. The first time I run the script, it fails as shown previously. But the second time works like a charm. I notice that the object of interest must be SELECTED before beginning the operation. Unfortunately, I used the "select <node>" command and that seems to fail; however by the time the first pass is done, the object would appear to be selected in the viewport, so the second time I run it - it works.

 

I tried desperately to stuff the code with selects and redraw calls and even sleep methods to make sure the object appears selected before the first attempt, but it refuses to work.

 

		else 
		(
			InitializeMorphModifier morphers
			select prevBaseModel
			completeRedraw()
			
			-- The Primary Loop; iterate over all morph targets, duplicate a base mesh,
			-- position it relative to previous base mesh, reset all morph sliders to 0%,
			-- and apply skin wrap. Set the appropriate morph target to 100%, and collapse the
			-- duplicate mesh and set it aside. Repeat for all other morph targets.
			for i = 1 to morphers.count do
			(
				newTarget = copy targetBaseModel
				newTarget.name = morphers[i].name
				
				-- Position the Models on top of each other
				PositionModel newTarget prevBaseModel
				
				morphModifier = prevBaseModel.modifiers["morpher"]
				select prevBaseModel --Important for updating in viewport?
				completeRedraw()
				
				-- Set the Morpher to 0%
				select prevBaseModel
				completeRedraw()
				WM3_MC_SetValue morphModifier i 0.0
				completeRedraw()
				
				-- SkinWrap
				skinwrapMod = Skin_Wrap()
				addModifier newTarget skinwrapMod
				skinwrapMod.engine = 1		-- VertexDeformation
				skinwrapMod.falloff = 0.001
				skinwrapMod.distance = 0.001
				skinwrapMod.meshList = append skinwrapMod.meshList(prevBaseModel)
				
				-- Set Morpher to 100%
				select prevBaseModel
				completeRedraw()
				WM3_MC_SetValue morphModifier i 100.0
				completeRedraw()

				-- The new target mesh should have the same final shape as the base,
				-- collapse the new target and set it aside
				CollapseStack newTarget
				newTarget.pos = morphers[i].pos + [0, 50, 0]
				
				-- Set the Morpher back to 0% for the next iteration
				select prevBaseModel
				completeRedraw()
				WM3_MC_SetValue morphModifier i 0.0
				completeRedraw()
			)
			
			-- Delete the temporary morph modifer
			deleteModifier prevBaseModel 1
		)

You will notice a lot of these redraw and select commands are redundant....

0 Likes