Notifications
Clear all

[Closed] Vertex Color Fill on edit Mesh Modifier

Hello guys !

I’m a bit stuck with something fairly simple…Via Maxscript, I’d like to add a modifier “etit Mesh” on an object and then fill the vertex color on this modifier. I want to do that to create a preview for multimate rendering in the viewport.

Could someone help me on this ?

21 Replies

Is there a way to create a modifier on top of an object which can fill vertex color information ?
So when the modifier is enabled you can see the vertex color and when it’s disabled the vertex color go back to “normal”.

For the moment I have this:


mesh_verts=$.numverts
vertsel = for v=1 to $.numverts collect v
polyop.setVertColor $ 0 vertsel [0,250,0]
update $

But it applies the vertex color on Edit poly object only and it’s not modifier based. So you can’t enable/disable it

you can also replace the “polyop.setVertColor $ 0 vertsel [0,250,0]” to “meshop.setVertColor $ 0 vertsel [0,250,0]” for edit mesh but it’s still not modifier based and it doesn’t work on primitive…

My plan is to use the vertex color as a previewer for RGB mate…

Please heeelp :rolleyes:

You could use the Unwrap UVW modifier.

Can you explain a little more please ?

We can use the Unwrap uvw modifier to set a vertex color ?

Yes, you can use the Unwrap modifier to set vertices colors, which are just positions with a different representation as a result.

Here is a very simple example. You can change the UV channel to the one you would like. Using this basic concept you can create a few routines to change the vertices colors of any geometry.

You might also need to take care of different preview environments the user may be using, like materials, drivers, etc. But that would be a second phase.

(
 	delete objects
 	
 	-- Test object
 	obj = converttomesh (geosphere radius:50 segs:1 baseType:0 isselected:on)
 	meshop.deletefaces obj #{1..3}
 	
 	-- Add Unwrap Modifier
 	channel = 10
 	
 	unwrap = unwrap_uvw()
 	addmodifier obj unwrap
 	unwrap.setMapChannel channel
 	
 	-- Enable viewport preview
 	obj.showVertexColors = on
 	obj.vertexColorType = 5
 	obj.vertexColorMapChannel = channel
 	
 	-- Set Vertex colors
 	unwrap.setVertexPosition currenttime 1 (red/255.0)
 	unwrap.setVertexPosition currenttime 2 (green/255.0)
 	unwrap.setVertexPosition currenttime 3 (blue/255.0)
 )

Thanks a lot for your post ! It’s really helping me !
Too bad it’s a per vertex method and not an array of vertex. It would operate faster.

If you would like, you can post the code you are using and we can try to optimize it. A test model or case is also welcome.

Why not use Vertex Paint Modifier?

-Eric

1 Reply
(@polytools3d)
Joined: 1 year ago

Posts: 0

I’ve never used neither the Unwrap UVW nor the Vertex Paint modifier for this previewing purpose.

The only right solution I would think of would be using the SDK, but the OP was related to the use of MXS and modifiers so I proposed the use of the Unwrap modifier.

Would you please let us know why do you think the Vertex Paint modifier would be a better choice over the Unwrap UVW modifier and how would you use it to accomplish this task?

You can use the same example I wrote in post #5 if you want.

This is what I’ve written for the moment. It’s not finished yet but the main functionality is working.
When there is a lot of vertices in the scene it takes quite a long time to run the script.
I don’t know anything about 3dsmax SDK. This is why I wanted to use maxscript but as expected it’s not fast If you have any idea to improve the speed I would be really grateful

try(destroyDialog Gbuffer_Viewer)catch()

/*===================================================
----------- Array to fill the interface and acces scene objects ------------------
===================================================*/
global ObjScene = #()
global ObjScene_str = #()
global MatId = #()
global MatId_str = #()
global Gbuffer_Viewer
global GbufferValue_List
global GbufferOjb_list

function paintVertex obj Mycolor = 
	(
		UVchannel = 99
		
		--create unwrap modifier
		unwrap = unwrap_uvw()
		unwrap.name = "Previewer"
		addmodifier obj unwrap
		unwrap.setMapChannel Uvchannel
		unwrap.setShowMapSeams off
		
		-- Enable viewport preview
		obj.showVertexColors = on
		obj.vertexColorType = 5
		obj.vertexColorMapChannel = UVchannel
		
		-- Set Vertex colors
		for o=1 to obj.numverts do
			(
			unwrap.setVertexPosition currenttime o (Mycolor*100)
			)
	)


--refresh object list when "All" radio checked
function RefreshAll = 
	(
		ObjScene = #()
		for o=1 to geometry.count do (append ObjScene geometry[o])
		
		ObjScene_str = #()
		for o=1 to geometry.count do (append ObjScene_str geometry[o].name)

		MatId = #()
		for o=1 to geometry.count do (append MatId geometry[o].gbufferchannel)

		MatId_str = #()
		for o=1 to geometry.count do (append MatId_str ((geometry[o].gbufferchannel )as string))
	)

	
--refresh object list when "Selected" radio checked
function RefreshSelected = 
	(
		ObjScene = #()
		for o in selection do (append ObjScene o)
		
		ObjScene_str = #()
		for o in selection do (append ObjScene_str o.name)

		MatId = #()
		for o in selection do (append MatId o.gbufferchannel)

		MatId_str = #()
		for o in selection do (append MatId_str ((o.gbufferchannel )as string))
	)

--Function to be called each time selection changes
Function SELcallback = 
	(
		if Gbuffer_Viewer.All_rad.state == 1 then 
		(
		RefreshAll ()
		Gbuffer_Viewer.GbufferOjb_list.items = ObjScene_str
		Gbuffer_Viewer.GbufferValue_List.items = MatId_str 
		)
		
		else
		(
		RefreshSelected ()
		Gbuffer_Viewer.GbufferOjb_list.items = ObjScene_str
		Gbuffer_Viewer.GbufferValue_List.items = MatId_str
		)
		
	)
	

--init interface 	

RefreshSelected ()

/*===================================================
---------------------------------------- Interface -------------------------------------------------
===================================================*/
rollout Gbuffer_Viewer "Object ID Previewer"
(
group "Object ID View and Assign"(
radiobuttons All_rad labels:#("All", "Selected") 	default:2	across:2 	offset:[-17,0]
spinner Gbuffer_spn "Object ID value: " 			width:125 	height:25  	bold:on			type:#integer 	range:[0,65535,0] offset:[25,0]

MultiListBox GbufferOjb_list "Scene Object " 		width:220 	height:25 	align:#left		offset:[0,0]	across:2		items:ObjScene_str
ListBox GbufferValue_List "Object ID" 				width:50 	height:25	align:#right 	offset:[0,0]	readOnly:on	 	items:MatId_str
)

group "Object ID Previewer"(
Spinner red_spn "R"					range:[0,65535,1]	width:60 	bold:on		type:#integer	offset:[-10,0] across:3
Spinner green_spn "G"				range:[0,65535,2]	width:60	bold:on		type:#integer	offset:[-20,0]
Spinner blue_spn "B"				range:[0,65535,3]	width:60 	bold:on		type:#integer	offset:[-30,0]

Checkbutton Preview_btn "PREVIEW MASK" 	width:150	bold:on		height:50		offset:[0,5] highlightColor:[00,80,80]  border:true
)

/*===================================================
-------------------------------- Spinner and Button action----------------------------------
===================================================*/
on Gbuffer_Viewer open do 
	(
	callbacks.addScript #selectionSetChanged "SELcallback()" id:#Rollout_Update
	RefreshSelected ()
	)

on Gbuffer_Viewer close do 
	(
	callbacks.removeScripts id:#Rollout_Update
	)
	
on Gbuffer_spn buttonup do 
	(
		with redraw off
		(	
		for o in GbufferOjb_list.selection do 
			(
			MatId_str[o] = (Gbuffer_spn.value as string)
			ObjScene[o].gbufferchannel = Gbuffer_spn.value 
			)
		GbufferValue_List.items = MatId_str
		)
	)--Spinner Object ID end

on Gbuffer_spn entered do 
	(
		with redraw off
		(	
		for o in GbufferOjb_list.selection do 
			(
			MatId_str[o] = (Gbuffer_spn.value as string)
			ObjScene[o].gbufferchannel = Gbuffer_spn.value 
			)
		GbufferValue_List.items = MatId_str
		)
	)--Spinner Object ID end	
	
on All_rad changed state do
	(
		if All_rad.state == 1 then 
		(
		RefreshAll ()
		GbufferOjb_list.items = ObjScene_str
		GbufferValue_List.items = MatId_str 
		)
		
		else
		(
		RefreshSelected ()
		GbufferOjb_list.items = ObjScene_str
		GbufferValue_List.items = MatId_str
		)
	)
	
on Preview_btn changed state do 
	(
-- 	global baseBG = backgroundColor 
-- 	backgroundColor = color 0 0 0
	if Preview_btn.checked == true do 
		(
			max create mode
			MySel = selection as array
			if Objscene != undefined do select Objscene
			for o in ObjScene do if superClassOf o == geometryClass do
				(
				case of 
					(
					(o.gbufferchannel == red_spn.value) : paintVertex o red
					
					(o.gbufferchannel == green_spn.value): paintVertex o green
					
					(o.gbufferchannel == blue_spn.value):  paintVertex o blue
						
					default : paintVertex o [0,0,0]
					)
				)
			clearSelection()
			select Mysel
		print "Preview ON"
		)
		
	if Preview_btn.checked == false do 
		(
		for o in ObjScene do if superClassOf o == geometryClass do
			(
			for m in o.modifiers where m.name == "Previewer" do (deletemodifier o m)
			o.showVertexColors = off
			)
		print "Preview OFF"
		)
		
		
	)
)--Rollout end
createDialog Gbuffer_Viewer width:295 height:518  style:#(#style_toolwindow,#style_sysmenu) 

The overall bottleneck is in PaintVertex() function, so here is an optimized version which runs 15 times faster for 12 objects 250K map vertices.

Also fixed a minor bug, note that the number of mesh vertices is not always the same as texture vertices.

function paintVertex obj Mycolor = 
(
	UVchannel = 99
	
	--create unwrap modifier
	unwrap = unwrap_uvw name:"Previewer"
	addmodifier obj unwrap
	unwrap.setMapChannel Uvchannel
	unwrap.setShowMapSeams off
	
	-- Enable viewport preview
	obj.showVertexColors = on
	obj.vertexColorType = 5
	obj.vertexColorMapChannel = UVchannel
	
	Mycolor /= 255.0 * 2.0
	SetVertexPosition = unwrap.setVertexPosition2
	
	-- Set Vertex colors
	for o=1 to unwrap.NumberVertices() do SetVertexPosition currenttime o Mycolor false false
		
	unwrap.updateview()
)
Page 1 / 2