1

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)

batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • 1
    could you add an image of result and expected result? UV maps 0 to 1 in U to image width and v to height. – batFINGER Feb 04 '21 at 15:20

2 Answers2

2

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.

batFINGER
  • 84,216
  • 10
  • 108
  • 233
1

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

IceSandwich
  • 136
  • 4