mirror of
https://github.com/EatTheFuture/compify.git
synced 2025-01-22 00:09:11 -05:00
Add UV margin setting.
It's a little hacky, but mostly works.
This commit is contained in:
parent
e65525da82
commit
d7aa7cc8ca
36
__init__.py
36
__init__.py
@ -36,6 +36,7 @@ from .node_groups import \
|
||||
ensure_footage_group, \
|
||||
ensure_camera_project_group, \
|
||||
ensure_feathered_square_group
|
||||
from .uv_utils import leftmost_u
|
||||
|
||||
MAIN_NODE_NAME = "Compify Footage"
|
||||
BAKE_IMAGE_NODE_NAME = "Baked Lighting"
|
||||
@ -99,6 +100,7 @@ class CompifyPanel(bpy.types.Panel):
|
||||
layout.separator(factor=1.0)
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.prop(context.scene.compify_config, "bake_uv_margin")
|
||||
layout.prop(context.scene.compify_config, "bake_image_res")
|
||||
|
||||
layout.separator(factor=1.0)
|
||||
@ -301,13 +303,29 @@ class CompifyPrepScene(bpy.types.Operator):
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
bpy.ops.uv.smart_project(
|
||||
angle_limit=(math.pi/180)*60, # 60 degrees
|
||||
island_margin=0.005,
|
||||
island_margin=0.001,
|
||||
area_weight=0.0,
|
||||
correct_aspect=False,
|
||||
scale_to_bounds=True,
|
||||
scale_to_bounds=False,
|
||||
)
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# We have to do the UV island margins twice, because Blender's
|
||||
# `island_margin` is stupid beyond belief and corresponds to
|
||||
# nothing absolute that we can depend on. So what we're doing
|
||||
# here is saying, "Hey, what was the actual margin achieved
|
||||
# with `island_margin=0.001`? Okay, now let's redo it based on
|
||||
# that result." It's still not 100% precise even with this,
|
||||
# but with a bit of buffer it's close enough.
|
||||
actual_margin = leftmost_u(context.selected_objects, UV_LAYER_NAME)
|
||||
actual_margin_pixels = actual_margin * context.scene.compify_config.bake_image_res
|
||||
target_margin_with_buffer = context.scene.compify_config.bake_uv_margin * (5.0 / 4.0)
|
||||
correction_factor = target_margin_with_buffer / actual_margin_pixels
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.uv.select_all(action='SELECT')
|
||||
bpy.ops.uv.pack_islands(rotate=False, margin = 0.001 * correction_factor)
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@ -333,7 +351,8 @@ class CompifyBake(bpy.types.Operator):
|
||||
and context.scene.compify_config.footage != None \
|
||||
and context.scene.compify_config.camera != None \
|
||||
and context.scene.compify_config.geo_collection != None \
|
||||
and len(context.scene.compify_config.geo_collection.all_objects) > 0
|
||||
and len(context.scene.compify_config.geo_collection.all_objects) > 0 \
|
||||
and compify_mat_name(context) in bpy.data.materials
|
||||
|
||||
def execute(self, context):
|
||||
# Clear operator fields. Not strictly necessary, since they
|
||||
@ -421,7 +440,7 @@ class CompifyBake(bpy.types.Operator):
|
||||
# filepath='',
|
||||
# width=512,
|
||||
# height=512,
|
||||
margin=4,
|
||||
margin=context.scene.compify_config.bake_uv_margin,
|
||||
margin_type='EXTEND',
|
||||
use_selected_to_active=False,
|
||||
max_ray_distance=0.0,
|
||||
@ -534,6 +553,15 @@ class CompifyFootageConfig(bpy.types.PropertyGroup):
|
||||
type=bpy.types.Collection,
|
||||
name="Footage Lights Collection",
|
||||
)
|
||||
bake_uv_margin: bpy.props.IntProperty(
|
||||
name="Bake UV Margin",
|
||||
subtype='PIXEL',
|
||||
options=set(), # Not animatable.
|
||||
default=4,
|
||||
min=0,
|
||||
max=2**16,
|
||||
soft_max=32,
|
||||
)
|
||||
bake_image_res: bpy.props.IntProperty(
|
||||
name="Bake Resolution",
|
||||
subtype='PIXEL',
|
||||
|
@ -1,37 +0,0 @@
|
||||
from math import inf
|
||||
from bpy_extras.mesh_utils import mesh_linked_uv_islands
|
||||
|
||||
|
||||
def uv_island_bbox_area_sum_multi_object(mesh_objects, uv_layer_name):
|
||||
area_sum = 0.0
|
||||
for obj in mesh_objects:
|
||||
area_sum += uv_island_bbox_area_sum(obj.data, uv_layer_name)
|
||||
return area_sum
|
||||
|
||||
|
||||
def uv_island_bbox_area_sum(mesh, uv_layer_name):
|
||||
""" Returns the sum of the area of the bounding boxes of all the UV
|
||||
islands in the given mesh for the given uv layer.
|
||||
"""
|
||||
uvs = mesh.uv_layers[uv_layer_name].data
|
||||
islands = mesh_linked_uv_islands(mesh)
|
||||
|
||||
bbox_area_sum = 0.0
|
||||
for island in islands:
|
||||
# Calculate the island's bounding box.
|
||||
min_u = inf
|
||||
max_u = -inf
|
||||
min_v = inf
|
||||
max_v = -inf
|
||||
for face_idx in island:
|
||||
for loop_idx in mesh.polygons[face_idx].loop_indices:
|
||||
uv = uvs[mesh.loops[loop_idx].vertex_index].uv
|
||||
min_u = min(min_u, uv[0])
|
||||
max_u = max(max_u, uv[0])
|
||||
min_v = min(min_v, uv[1])
|
||||
max_v = max(max_v, uv[1])
|
||||
|
||||
# Add it's area to the sum.
|
||||
bbox_area_sum += ((max_u - min_u) * (max_v - min_v))**0.5
|
||||
|
||||
return bbox_area_sum
|
10
uv_utils.py
Normal file
10
uv_utils.py
Normal file
@ -0,0 +1,10 @@
|
||||
from math import inf
|
||||
|
||||
|
||||
def leftmost_u(mesh_objects, uv_layer_name):
|
||||
leftmost = inf
|
||||
for obj in mesh_objects:
|
||||
uvs = obj.data.uv_layers[uv_layer_name].data
|
||||
for uv in uvs:
|
||||
leftmost = min(leftmost, uv.uv[0])
|
||||
return leftmost
|
Loading…
Reference in New Issue
Block a user