import bpy from math import atan2, pi # Delete default cube if present # Our delete all function would have worked fine too if "Cube" in bpy.data.objects: bpy.data.objects["Cube"].select_set(True) bpy.ops.object.delete() bpy.ops.mesh.primitive_uv_sphere_add(radius=5, segments=640) sphere = bpy.context.active_object # Only need one material material = bpy.data.materials.new(name=f"FaceMaterial") material.use_nodes = True texture = bpy.data.images.load("earth.jpg") bpy.ops.object.mode_set(mode='EDIT') bpy.ops.uv.unwrap(method='ANGLE_BASED') # Will this work? bpy.ops.object.mode_set(mode='OBJECT') sphere.data.materials.append(material) bsdf_node = material.node_tree.nodes.get("Principled BSDF") texture_node = material.node_tree.nodes.new(type="ShaderNodeTexImage") texture_node.image = texture material.node_tree.links.new(texture_node.outputs["Color"], bsdf_node.inputs["Base Color"]) for i, poly in enumerate(sphere.data.polygons): # Get the UV layer for the face uv_layer = sphere.data.uv_layers.active.data # Copy over uv values for j, loop_index in enumerate(poly.loop_indices): vco = sphere.data.vertices[poly.vertices[j]].co uv_layer[loop_index].uv = (1.0 - (pi + atan2(vco.x, vco.y) / (2*pi)) % 1.0 , 0.5 + (vco.z / 10)) print(atan2(vco.x, vco.y))