3
$\begingroup$

I want to be able to use Smart UV project on thousands of separate objects in a scene at once.

I'm wanting the result to be as if I'd applied the Smart UV Project to each individual object one at a time.

Using A to select all and SPACE then Smart UV Project just seems to create a problem in sense that when I import even a single object into Unreal Engine it behaves like it has an enormous footprint bigger than my terrain map, even though the object itself does not and is small.

Any advice or suggestions would be most welcome.

$\endgroup$

3 Answers 3

9
$\begingroup$

Scripting with Python

As you mentioned, Smart Unwrap in object mode takes all the objects as a whole. It's more useful to create a texture atlas, rather than individual UV maps.

Like in most scenarios where a tedius task must be done several times, you can try to automate the process with python code. You can write a script that iterates through all the selected object of the scene, enter edit mode for each object, select all the elements of the object an call the smart_project() operator.

Blender 2.8+

import bpy

# Get all objects in selection
selection = bpy.context.selected_objects

# Get the active object
active_object = bpy.context.active_object

# Deselect all objects
bpy.ops.object.select_all(action='DESELECT')

for obj in selection:
    # Select each object
    obj.select_set(True)
    # Make it active
    bpy.context.view_layer.objects.active = obj
    # Toggle into Edit Mode
    bpy.ops.object.mode_set(mode='EDIT')
    # Select the geometry
    bpy.ops.mesh.select_all(action='SELECT')
    # Call the smart project operator
    bpy.ops.uv.smart_project()
    # Toggle out of Edit Mode
    bpy.ops.object.mode_set(mode='OBJECT')
    # Deselect the object
    obj.select_set(False)

# Restore the selection
for obj in selection:
    obj.select_set(True)

# Restore the active object
bpy.context.view_layer.objects.active = active_object

Blender 2.7x

import bpy

if bpy.context.selected_objects != []:
    for obj in bpy.context.selected_objects: #loop through all the selected objects
        if obj.type == 'MESH':
            bpy.context.scene.objects.active = obj
            bpy.ops.object.editmode_toggle() #entering edit mode
            bpy.ops.mesh.select_all(action='SELECT') #select all objects elements
            bpy.ops.uv.smart_project() #the actual unwrapping operation
            bpy.ops.object.editmode_toggle() #exiting edit mode

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Thanks Carlo, you are an absolute superstar for putting me on the right track with this. I'd no idea you could use python for automation of tasks as I'm new to Blender. Using a "for each" to select each object in a loop and apply the UV Smart Project seems to work perfectly. :-) $\endgroup$
    – James
    Commented Mar 16, 2018 at 0:12
0
$\begingroup$

I took the origin code by Carlo and have created an small AddOn that can be installed in Blender.

This is my very first Blender Add-On and I'm not a good coder... So it’s nothing special, but helped me a lot.

What it does:

  • It executes the Smart UV project function to all selected mesh objects in the scene.
  • Correct Aspect ratio is always ON, Stretch to UV Bounds is always OFF.
  • After the regular installation in the preferences you can activate the Add-On by pressing the spacebar and type „Smart“ in. Then „Smart UV project selected objects“ appear and you can execute it.

The quick script helped me a lot here. I hope it's something for you too.

Here is the link for the download:

http://www.christoph-werner.de/2018/08/03/smart-uv-project-all-selected-objects-blender-add-on/

Best wishes

Chris

$\endgroup$
0
$\begingroup$

Too bad it doesn't work in blender 2.9. I'd like to use this thing.

edit: trying change this: bpy.context.scene.objects.active = obj to this: bpy.context.view_layer.objects.active = obj

edit: yes, 2.9 tested enter image description here

edit: The output of this script creates one UV layout for all objects - it's not good for me, I want each object to have its own uv layout (for lightmapping) - I have to redo it for my purposes. This is my second day with Python, thank you Carlo and Christoph Werner for the inspiration.

edit:

import bpy

print("________________________________________START")

selection_names = [] #declaring array

for obj in bpy.context.selected_objects: #loop through all the selected objects
  if obj.type == 'MESH':
    selection_names.append(obj) #add to array
    obj.select_set(False)

if selection_names != []:
    for obj in selection_names: #loop through array
            bpy.context.view_layer.objects.active = obj
            lm = obj.data.uv_layers.new(name="LightMap") #new UV layer for lightmapping
            lm.active = True
            bpy.ops.object.editmode_toggle() #entering edit mode
            bpy.ops.mesh.select_all(action='SELECT') #select all objects elements
            bpy.ops.mesh.remove_doubles(threshold=0.001, use_unselected=False) #optimize vertex- not necessary for low-poly
            bpy.ops.uv.smart_project(angle_limit=66.0, island_margin=0.222, user_area_weight=0.0, use_aspect=True, stretch_to_bounds=False) #the actual unwrapping operation
            bpy.ops.object.editmode_toggle() #exiting edit mode

print("________________________________________END")
$\endgroup$
2
  • 1
    $\begingroup$ This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. - From Review $\endgroup$ Commented Sep 18, 2020 at 13:55
  • 1
    $\begingroup$ Thank you, your comment is very stimulating, however I am just trying to solve the original query so that it works for me in version 2.9. If, due to your high experience, you can solve it, please send a solution. Thank you. $\endgroup$
    – user106549
    Commented Sep 18, 2020 at 15:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .