1
$\begingroup$

I have a mesh that represents a piece of paper. This mesh can be unwrapped to a rectangle surface. When I select all faces and then unwrap to get the UV. I obtain the following :

enter image description here

The problem is that the UVMap does not cover the full rectangle image. How can I make the UVMap automatically distort in a way that it covers the full image?

Additional question, how can I do that using the Python scripting API?

Thank you very much for you help!

Edit : If I disable the Correct Aspect option I get the following result, which is even worse

enter image description here

$\endgroup$
5
  • $\begingroup$ When you unwrap, what does it give if you disable the Correct Aspect option in the Operator Box? $\endgroup$
    – moonboots
    Commented Jul 25, 2023 at 9:19
  • $\begingroup$ I added an edit to the original post. If I disable the Correct Aspect option in the Operator Box it gets worse ... $\endgroup$ Commented Jul 25, 2023 at 9:29
  • $\begingroup$ Could you please pack your image (File > External Data > Pack Resources) and share your file (this object only)? $\endgroup$
    – moonboots
    Commented Jul 25, 2023 at 11:04
  • $\begingroup$ Sure here is a link to the file drive.google.com/file/d/1liaqbAXiy2mDay1ZNKHVk0-eeww-sOzV/… $\endgroup$ Commented Jul 25, 2023 at 11:09
  • $\begingroup$ there may be a simple function but I don't know it, you can do it manually but it's a bit tedious (UV > Constrain to Image Bounds, choose the 2D Cursor as pivot, put the 2D cursor at 0:0, scale your UV island on X and Y) $\endgroup$
    – moonboots
    Commented Jul 25, 2023 at 12:49

2 Answers 2

1
$\begingroup$

I could not find any function to achieve what I wanted automatically, so I wrote a small script that does that. Here it is (works with Blender 3.5.1):

import bpy
import numpy as np

obj = bpy.context.active_object
# Apply the linear unwrap, to make the UVMap fit the [0, 1] range

# First find the min and max UV coordinates
max_u, min_u = -np.inf, np.inf
max_v, min_v = -np.inf, np.inf

for face in obj.data.polygons:
    for loop_idx in face.loop_indices:
        uv_coords = obj.data.uv_layers.active.data[loop_idx].uv
        if uv_coords.x > max_u:
            max_u = uv_coords.x
        if uv_coords.x < min_u:
            min_u = uv_coords.x
        if uv_coords.y > max_v:
            max_v = uv_coords.y
        if uv_coords.y < min_v:
            min_v = uv_coords.y

# Fit a linear function to the UV coordinates
def fit_linear(x0, y0, x1, y1):
    a = (y1 - y0) / (x1 - x0)
    b = y0 - a * x0
    return a, b

margin = 0.0001  # Margin to leave between the UV coordinates and the [0, 1] range

a_u, b_u = fit_linear(min_u, 0 + margin, max_u, 1 - margin)
a_v, b_v = fit_linear(min_v, 0 + margin, max_v, 1 - margin)

# Apply the linear function to the UV coordinates
for face in obj.data.polygons:
    for loop_idx in face.loop_indices:
        uv_coords = obj.data.uv_layers.active.data[loop_idx].uv
        uv_coords.x = a_u * uv_coords.x + b_u
        uv_coords.y = a_v * uv_coords.y + b_v

This piece of code basically takes the current UVMapping and stretches to the [0, 1] range in both directions, thus covering the entire image.

Here is an example of a result: Before applying the script, the UVMap does not cover the full image Before applying the script, the UVMap does not cover the full image.

After applying the script, the UVMap covers the full image. After applying the script, the UVMap covers the full image.

So in the end the script is a sort of equivalent of the Scale to Bounds option of the cube projection UVMapping.

$\endgroup$
1
  • $\begingroup$ wow nice!.......... $\endgroup$
    – moonboots
    Commented Jul 26, 2023 at 15:48
-1
$\begingroup$

Use Cube projection for unwrapping and select the Scale to Bounds option.Cube projection. (As far as I understand) Cube Projection projects the geometry on faces of a cube and creates a uv map based on these faces. Now since cube projection does have an option to scale to bounds, what will happen is that. your UV map is scaled to fit perfectly within the UV 0-1 space. enter image description here

$\endgroup$
1
  • $\begingroup$ The problem is that, as can be seen in my first image, the original paper is not flat, it's a curved piece of paper, so this will not work. Thanks anyway $\endgroup$ Commented Jul 25, 2023 at 11:11

You must log in to answer this question.

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