1
$\begingroup$

I am trying to enlarge the uv map using python scripting so more square in my texture. Not sure what is wrong.

bpy.ops.object.select_all(action='DESELECT')
XYZcoord = (0, 0 ,0)
ob = bpy.ops.mesh.primitive_plane_add(location=XYZcoord)
bpy.ops.transform.resize(value=( 20, 20, 20))
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.subdivide(number_cuts=10)
bpy.ops.uv.smart_project()
bpy.ops.object.mode_set(mode="OBJECT")
material_image = bpy.data.materials.new(name= "Basic_Texture")
material_image.use_nodes = True
principled_node = material_image.node_tree.nodes.get('Principled BSDF')
principled_node.inputs[7].default_value = 0.08
texImage = material_image.node_tree.nodes.new('ShaderNodeTexImage')
texImage.location = (-300, 400)
texImage.image = bpy.data.images.load("H:\\blender__texture_maps_ao_normal_height_etc\\Wooden_planks_04_2K_Base_Color.png")
material_image.node_tree.links.new(principled_node.inputs['Base Color'], texImage.outputs['Color'])
texImage_rough = material_image.node_tree.nodes.new('ShaderNodeTexImage')
texImage_rough.location = (-300, 0)
texImage_rough.image = bpy.data.images.load("H:\\blender__texture_maps_ao_normal_height_etc\\Wooden_planks_04_2K_Roughness.png")
texImage_rough.image.colorspace_settings.name = 'Non-Color'
material_image.node_tree.links.new(principled_node.inputs['Roughness'], texImage_rough.outputs['Color'])
bpy.ops.object.shade_smooth()
bpy.context.object.active_material = material_image


bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.uv.select_all(action='SELECT')
bpy.ops.mesh.select_mode(type='EDGE')
bpy.context.area.ui_type = 'UV'
bpy.ops.transform.resize(value=(2, 2, 2), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=True, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
bpy.ops.object.mode_set(mode='OBJECT')
print(bpy.context.active_object) 
$\endgroup$
1
  • 1
    $\begingroup$ could you add an image of result and expected result? UV maps 0 to 1 in U to image width and v to height. $\endgroup$
    – batFINGER
    Feb 4, 2021 at 15:20

2 Answers 2

2
$\begingroup$

Reducing Operators

Currently the question code has 14 operators, most of which can be easily replaced with API methods.

Python performance with Blender operators

Creating the grid.

Replace the add plane, subdivide scale with a single create primitive grid operator. Could also replace this operator

import bpy

bpy.ops.mesh.primitive_grid_add(
        location=(0, 0, 0),
        x_subdivisions=12,
        y_subdivisions=12,
        size=2,
        )
grid = bpy.context.object
grid.scale *= 20
me = grid.data

or to apply scale, and have unit scale grid

import bpy

bpy.ops.mesh.primitive_grid_add(
        x_subdivisions=12,
        y_subdivisions=12,
        size=40,
        )
grid = bpy.context.object
me = grid.data

The UV is generated with the primitive, so no need to UV project in this instance.

enter image description here The operator generated UV

Scaling UV with numpy.

In regard to scaling the UV, if we have a mesh with a UV can use something like below, to scale by (scale_u, scale_v) about some UV center point. This is the same result as @IceSandwich without iterating over the UVs via loops

import bpy
import numpy as np
from mathutils import Matrix
center = (0.5, 0.5)
scale = (2, 2)

ob = bpy.context.object
me = ob.data
uv_layer = me.uv_layers.active

uvs = np.empty((2 * len(uv_layer.data), 1), "f")
uv_layer.data.foreach_get('uv', uvs)
S = Matrix.Diagonal(scale)
scaled_uvs = np.dot(uvs.reshape((-1, 2)) - center, S) + center
uv_layer.data.foreach_set('uv', scaled_uvs.ravel())

will elaborate more if need be after question edit.

$\endgroup$
1
$\begingroup$

Maybe u forget to add 'R' before the file path?

bpy.data.images.load(R"H:\blender__texture_maps_ao_normal_height_etc\Wooden_planks_04_2K_Base_Color.png")

It should raise an error in python but my blender doesn't show any error message. Everything works fine in my blender.

Edit: You can use the following code to scale your uv instead of using bpy.ops.transform.resize See more information here

me = bpy.context.object.data
uv_layer = me.uv_layers.active.data

scale_factor = 2
for poly in me.polygons:
    for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
        # rearrange uv coordinate from 0~1 to -1~1 and scale it.
        uv_layer[loop_index].uv.x = (uv_layer[loop_index].uv.x - 0.5) * 2 * scale_factor / 2 + 0.5
        uv_layer[loop_index].uv.y = (uv_layer[loop_index].uv.y - 0.5) * 2 * scale_factor / 2 + 0.5
$\endgroup$
1
  • $\begingroup$ the issue it not the image... it scaling the mesh. $\endgroup$ Feb 1, 2021 at 23:37

You must log in to answer this question.

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