Notifications
Clear all

[Closed] Script to Planar Map UVs of Each Poly in a Mesh

I’m trying to write a script that will take any random Editable Poly object, apply an Unwrap_UVW modifier, then Quick Planar Map every polygon in the object individually, normalize all these UV-islands relative to each other, and pack them inside a 1-unit UV space without overlap.

Can anyone help me write this script? Here’s what I got so far:


 mybox = Box length:10 width:10 height:10;
 unwrapper = addModifier mybox (Unwrap_UVW());
 subobjectLevel = 3;
 mybox.Unwrap_UVW.unwrap6.selectFacesByNode #{9..10} $;
 mybox.Unwrap_UVW.planarMap();
 

This script simply creates a cube, applies the modifier, tries to select a particular face, and applies a quick planar map. It works, but I need to generalize it to any mesh and have it loop through all the polygons. I’m not sure how to comprehensively loop through every polygon once inside the Unwrap_UVW modifier.

Questions:

  1. How can I get a bitarray of every polygon in the object so I can use it with: selectFacesByNode #{9…10}?
  2. How can I normalize every planar-mapped polygon so that UVs on smaller polygons use up proportionately less UV space? (Basically I want the checker patterns to be the same size on each polygon, even though some polygons are larger than others.)
  3. How can I pack all of these UV-islands into a single UV tile without overlap?

Thanks for helping me out!

8 Replies
1 Reply
(@plastic)
Joined: 11 months ago

Posts: 0

Poly.faces as bitarray

but what about the seams? the checkers wouldn’t meet anymore.
can you illustrate what you’re trying to do?

I’ve come up with the following after much trial and error, but Max throws an exception when I run this script, even though the individual lines seem to work fine. I’ve been hitting my head against the wall trying to figure out why this code won’t run smoothly. Does Max have glitchty execution of some functions, or am I doing it wrong?


 print "*************************";
 mybox = Box length:10 width:5 height:2;
 ConvertTo mybox Editable_Poly;
 polyCount = polyop.getNumFaces mybox;
 addModifier mybox (Unwrap_UVW());
 mybox.Unwrap_UVW.unwrap2.setTVSubObjectMode 3;
 
 for i = 1 to polyCount do
 (
 	mybox.Unwrap_UVW.unwrap.selectPolygons #{i};
 	mybox.Unwrap_UVW.unwrap2.unfoldMap 0;
 )
 mybox.Unwrap_UVW.unwrap.selectPolygons #{1..polyCount};
 mybox.Unwrap_UVW.unwrap2.pack 1 0.02 true true true;
 

I got it working! Well, almost.

What I’m trying to do: I want to planar map every single polygon in every mesh in my scene individually. Yes, the seams won’t match up, but that’s no problem because I will be texturing in Mudbox and don’t care about seams. All I need are flat, no-overlapping UVs.


print "*********************************************";
theObjects = objects as array;
for i = 1 to theObjects.count do 
(
	selectedObj = theObjects[i];
	print "Processing Object: ";
	print i;
	if (selectedObj.isHidden == false or selectedObj.isFrozen == false) then
	(
		ConvertTo selectedObj Editable_Poly;
		polyCount = polyop.getNumFaces selectedObj;
		unwrapper = addModifier selectedObj (Unwrap_UVW());
		max modify mode;
		select selectedObj;
		selectedObj.Unwrap_UVW.unwrap2.setTVSubObjectMode 3;
			
		for j = 1 to polyCount do
		(
			selectedObj.Unwrap_UVW.unwrap.selectPolygons #{j};
			selectedObj.Unwrap_UVW.unwrap2.unfoldMap 0;
		)
		
		selectedObj.Unwrap_UVW.unwrap.selectPolygons #{1..polyCount};
		selectedObj.Unwrap_UVW.unwrap2.pack 1 0.02 true true true;
		print "Object Unwrapped";
		print "-----------------";
	)
	else
	(
		print "Object Skipped: Hidden or Frozen";
	)
)

The above code works pretty well, but I throws an error if I have non-mesh objects in my scene. Obviously it makes no sense to unwrap a Camera or Spline. How can I write a quick if-statement to test for whether the object in my scene is a mesh/poly object?

“theObjects = objects as array”
replace “objects” with “geometry”

You can do it easier than that as there is no need to manually map each face. Instead use a UVW Map set to Face mode, then Add the Unwrap and pack using normalized clusters. Uses 2 modifiers, instead of one, but should be faster to implement and run.

-Eric

Thanks for the suggestion Eric, but it does not yield the result I want. I need every face to get mapped without distortion and proportional to its size. UVW Map Face doesn’t do it:

http://screencast.com/t/VAyP3q4h

After unwrapping some more models with my script, I notice that using Unfold Map on each face doesn’t work either because some long polygons don’t get scaled proportionally, resulting in an uneven checker pattern. From what I’ve tried, a Quick Planar Map on each face is the only technique that gets the perfectly straight results I need, but I cannot get Quick Planar Map to work with MaxScript. The documentation says that the following should work:


  selectedObj.Unwrap_UVW.unwrap.setProjectionType 4;
  selectedObj.Unwrap_UVW.unwrap.planarMap();
  

But the results are NOT the same as pressing the Quick Planar Map button in the UVW Unwrap modifier with the Mouse. I’ve tried looking for a hotkey or shortcut that I could script to press that button, but I’m not sure that’s even possible. Is there any way to get the Quick Planar Map working via script? Can I set a shortcut for it in Preferences and activate that shortcut via MaxScript?

P.S. When I use the MacroRecorder to track the pressing of Quick Planar Map via Mouse, it doesn’t yield any output. Does that mean there is no script equivalent to this action? It can only be done by hand?

Hi liquidgraph,

I just came along this thread since i would also need a fast solution for
creating per poly uvw tiles for baking reasons.

I use Flatiron and unwrella in 3dsmax but with heavy geometry it takes forever to unwrap.
Specially since the use only one core.

Are there any news on your try to script this with “Quick Planar Mesh” ?

doublepost