2

If I unwrap my model's UVs, I get lots of squares (or square-like things) like this:

enter image description here

But the squares are really tiny! I don't want the squares to be tiny, I want each island of connected vertices to fill the entire picture.Or, if they're like the triangles or other weird shapes, to expand as far as reasonably possible.

Note, if I unwrap each square individually it fills the picture as desired (but this is impractical for 100+ squares)

I do not care about overlapping UVs.

How would I do this?

Download my tree scene here

Joehot200
  • 592
  • 2
  • 7
  • 28

2 Answers2

3

Quick script in order to select all islands and pack them individually based on How to get lists of UV island from Python script?. Credit goes to @Tlousky, I just added bpy.ops.uv.pack_islands():

enter image description here UV layout before (left) and after running the script (right)


Just select your object in Object Mode and run the following script:

import bpy
C = bpy.context
o = bpy.data.objects[ C.object.name ]

Go to object mode to read UV data

bpy.ops.object.mode_set( mode = 'OBJECT' )

uvLayer = o.data.uv_layers.active uvs = [ uvLayer.data[i] for i in range( len( uvLayer.data ) ) ]

others = uvs.copy() islands = []

def select_island( uv ): uv.select = True bpy.ops.object.mode_set( mode = 'EDIT' ) bpy.ops.uv.select_linked() bpy.ops.uv.pack_islands() bpy.ops.object.mode_set( mode = 'OBJECT' )

return [ i for i, uv in enumerate( uvs ) if uv.select ]

for i in range( len( uvs ) ): bpy.ops.object.mode_set( mode = 'EDIT' ) bpy.ops.uv.select_all( action = 'DESELECT' ) bpy.ops.object.mode_set( mode = 'OBJECT' )

flat = [ idx for isle in islands for idx in isle ]
if i in flat: continue

island = select_island( uvs[i] )

exists = len( set( flat ).intersection( set( island ) ) )
if island and not exists: islands.append( island )


#print( islands ) #print( " number of islands: ", len( islands ) )

brockmann
  • 12,613
  • 4
  • 50
  • 93
1

I've written a small script that should get you where you need to be. Please be aware I'm no programmer at all, so this script might objectively suck, but it does work (tested it on your scene), even though it needs a bit of prep:

  • First, separate each object (each leaf) into a separate object. This is easiest done by first separating the leaves from the bark (Edit Mode - Material tab - Select faces with this material - P - selection), then going into them in Edit mode and choosing P - By Loose Parts.
  • Then, select all the leaf objects and run this script:
    import bpy
selection = bpy.context.selected_objects #remember the currently selected objects as "selection"

for ob in selection: 
    ob.select_set(False) #deselect everything. 
    #Otherwise when unwrapping each object, the algorithm seems to consider its fellow objects' UVs. 

for i in selection: #do the following for each of the objects:
    bpy.context.view_layer.objects.active = i #set as active
    bpy.ops.object.mode_set(mode='EDIT') #go into edit mode
    bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=0.001) #unwrap
    bpy.ops.object.mode_set(mode='OBJECT') #exit out of edit mode. This is optional.

BuzzKirill
  • 452
  • 3
  • 15