Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Projection modifier: I'm trying to project UV channel 2 from multiple LOD0 objects, to the correspond LOD1 and LOD2, by maxscripting

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
unmarti
392 Views, 8 Replies

Projection modifier: I'm trying to project UV channel 2 from multiple LOD0 objects, to the correspond LOD1 and LOD2, by maxscripting

Hello there,
I created the following macroscript, with the intention of projecting UV map channel 2, from multiple selected objects (LOD0), to their corresponding low resolution objects (LOD1 and LOD2):

 

macroscript MyCustomTool2
category:"MyTools"
tooltip:"Project UVs multiple LOD0"
(
	rollout projectMutipleUVsRollout "Project UVs"
	(
		button projectMutipleUVsButton "Project UVs"
		
		on projectMutipleUVsButton pressed do
		(
			-- Retrieve the selected objects
			local selectedObjects = selection as array
			
			-- Check if any objects are selected
			if selectedObjects.count > 0 then
			(
				-- Loop through each selected object
				for z = 1 to selectedObjects.count do
				(
					-- Add Projection modifier to the selected object
					local obj = selectedObjects[z]
					local projMod = Projection ()
					addModifier obj projMod
					
					-- Get the name of the selected object
					local objName = obj.name

					-- Extract the base name
					local baseName = substring objName 1 (objName.count - 1)
					
					-- Iterate through all objects in the scene					
					for i = 1 to objects.count do
					(
						local currObj = objects[i]
						local currObjName = currObj.name

						-- Check if the object name matches the pattern 
						if (findString currObjName baseName) == 1 and (currObjName != objName) do
						(
							--Add the matched object to the Reference Geometry List
							projMod.addObjectNode currObj
							
						)
					)
					
					--Add a Projection Mapping
					projMod.addRegisteredProjectionType 1
					pMap = projMod.getProjectionType 1
					
					--Get that Projection Mapping for work with it
					pMap = projMod.getProjectionType 1
					
					--Assign UV map channels
					pMap.sourceMapChannel = 2
					pMap.sameAsSource = false
					pMap.targetMapChannel = 2
					
					projMod.projectAll()
				
				)
				
				-- Display a message
				messageBox "UV projection completed."
			)
			else 
			(
				-- Display a message if no objects are selected
				messageBox "No objects selected." title:"Error"
			)
		)
	)

	createDialog projectMutipleUVsRollout 250 50
)

 

 

 

If I only select one object (LOD0), it works perfectly, but when I select multiple objects, I don't understand why, but "projMod.addRegisteredProjectionType 1" doesn't seem to work, and the code breaks after that. So, if any one could explain to me why these is happening, and give me some solution, I'll be really grateful. Thanks for your time.

Tags (2)
8 REPLIES 8
Message 2 of 9
denisT.MaxDoctor
in reply to: unmarti

Why code as a .PNG image? To have fun with the conversion?
Would you prefer an answer in ancient Egyptian to continue the fun?

Message 3 of 9
unmarti
in reply to: denisT.MaxDoctor

Sorry Denis, this is my first post, I still have a lot to learn. But no please,
ancient Egyptian is not one of my best languages.
Message 4 of 9
denisT.MaxDoctor
in reply to: unmarti

so post the code again as text please.

 

denisTMaxDoctor_0-1713729558560.png

 

Message 5 of 9
unmarti
in reply to: denisT.MaxDoctor

Thanks for the minitutorial Denis
Message 6 of 9
denisT.MaxDoctor
in reply to: unmarti

the system tries to avoid a "dependency loop" and cannot add a target with an already added source as a target in another projection modifier. Thus, it is necessary to check and determine which targets should be excluded from the projection.

 

more specifically...

if the list of projected targets is empty, the projection modifier returns an undefined projection object with (pmod.getProjectionType 1)

 

Message 7 of 9
denisT.MaxDoctor
in reply to: unmarti

for example:

 

mapped fn add_projection_mod obj targets: = 
(
	local pmod = Projection()

	-- make the projection modifier a current edit object: 
	max modify mode 
	select obj
	modPanel.addModToSelection pmod
	
	if targets == unsupplied do targets = geometry as array
	
	for target in targets do --> where not refs.DependencyLoopTest target obj do 
	(
		----- the system checks for dependency loop >> 
		pmod.addObjectNode target
	)
	
	pmod.addRegisteredProjectionType 1 -- works only if pmod is a current edit ModPanel object: 
	
	if (pobj = pmod.getProjectionType 1) != undefined do
	(
		--format "object:% map:%\n" obj pobj

		pobj.sourceMapChannel = 2
		pobj.sameAsSource = false
		pobj.targetMapChannel = 2
			
		pmod.projectAll()
	)
) 

delete objects
for k=0 to 3 do box pos:[k*40,0,0]
select objects

add_projection_mod (selection as array)	

 

 

 

 

 

Message 8 of 9
unmarti
in reply to: denisT.MaxDoctor

Wow! That works perfectly! Thank you very much Denis! Just by reading and understanding a few lines of your code, I learned a lot, I really appreciate it man. Thank you for your time, and for all the time you have saved me.

 

I'll post my final code below, in case it helps anyone else.

 

macroscript MyCustomTool_001
category:"MyTools"
tooltip:"UV Channel Projection"
(
	rollout projectMutipleUVsRollout	"UV Channel Projection"
	(
		spinner sourceUV "Source UV Channel:" range:[1, 100, 2] type:#integer width:150 pos:[35,10]
		spinner targetUV "Target UV Channel:" range:[1, 100, 2] type:#integer width:150 pos:[35,35]
		
		button btnProjectUVs "Project UVs" width:150 height:30 pos:[25,70]
		
		on btnProjectUVs pressed do
		(
			global val1 = sourceUV.value
			global val2 = targetUV.value
			
			mapped fn add_projection_mod obj targets: =
			(
				local refList = #()
				
				local pMod = Projection ()
				
				-- make the projection modifier a current edit object:  
				--> go to modify mode
				max modify mode
				
				select obj
				modPanel.addModToSelection pMod
				
				-- Get the name of the selected object
				local objName = obj.name
				
				-- Extract the base name
				local baseName = substring objName 1 (objName.count - 1)

				if targets == unsupplied do targets = geometry as array
					
				for target in targets do --> where not refs.DependencyLoopTest target obj do 
				(
					-- Get the name of the possible target
					local targetName = target.name
					--Compare with the base name of the selected object
					if (findString targetName baseName) == 1 and (targetName != objName) do
					(
						----- the system checks for dependency loop >> 
						--Add the matched object to the Reference Geometry List
						pMod.addObjectNode target
						append refList target
					)
				)	
				
				--Add a Projection Mapping
				pMod.addRegisteredProjectionType 1 -- works only if pmod is a current edit ModPanel object: 
	
				if (pMap = pMod.getProjectionType 1) != undefined do
					(
						--format "object:% map:%\n" obj pobj

						pMap.sourceMapChannel = val1
						pMap.sameAsSource = false
						pMap.targetMapChannel = val2
						
						pMod.projectAll()
						
						for ref in refList do ( collapseStack ref )
						
						deleteModifier obj pMod
					)
				
			)
			
			-- Retrieve the selected objects
			local selectedObjects = selection as array
			
			-- Check if any objects are selected
			if selectedObjects.count > 0 then
			(
				--Call function
				add_projection_mod (selectedObjects)
				
				messageBox "UV projection completed."
			)
			else 
			(
				-- Display a message if no objects are selected
				messageBox "No objects selected." title:"Error"
			)
		)
	)

	createDialog projectMutipleUVsRollout 200 120
)
Message 9 of 9


@denisT.MaxDoctor wrote:

more specifically...

if the list of projected targets is empty, the projection modifier returns an undefined projection object with (pmod.getProjectionType 1)

 


By the way, this sentence is incorrect. The projection target list (if it is empty, for example) does not affect the definition of the projection-type object. As I said in the code, the problem is that MXS has no method to add a registered projection type to an "inactive" modifier. The modifier must be selected as the current edit object in the modifier panel to initialize its local data and make the projection-type object defined.       

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report