2
$\begingroup$

I want to create a large set of spiral galaxies with textures using a python script.

I managed to create shader nodes and links to set up a material.

enter image description here

For the spiral shape, I need to perform a transformation of the standard uv-mesh. The transformation is written below. Basically, it is a proportional editing, where the center row of the rectangular mesh is grabbed and shifted horizontally.

enter image description here

bpy.ops.object.editmode_toggle()
bpy.ops.transform.translate(value=(1.03353, 0.00369117, 0), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=True, use_proportional_edit=True, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)

How can I include this transformation in the python script? My script has the following structure:

 bpy.ops.mesh.primitive_uv_sphere_add(radius = 5, enter_editmode = False, location=(x,y,z))
 sphere = bpy.context.active_object
  
 sphere.data.materials.append(get_material(i))
 sphere.scale[2]=0.1

and the function get_material(index)

def get_material(index):
    mat = bpy.data.materials.new("GalaxyMaterial"+str(index))
 
    mat.use_nodes = True
    node_tree = mat.node_tree
    nodes = node_tree.nodes

    output = nodes.get("Material Output")
    bsdf = nodes.get("Principled BSDF") 

    links =mat.node_tree.links

    node_coord = nodes.new(type="ShaderNodeTexCoord")

    node_texture = nodes.new(type='ShaderNodeTexNoise')

    links.new(node_coord.outputs[2],node_texture.inputs[0])
    node_texture.inputs[2].default_value=18
    node_texture.inputs[3].default_value=5.3
    node_texture.inputs[4].default_value=0.567
    node_texture.inputs[5].default_value=1.1

    node_ramp = nodes.new(type='ShaderNodeValToRGB')

    node_ramp.color_ramp.elements[0].color = (0,0,0,1)
    node_ramp.color_ramp.elements[0].position=0.45
    node_ramp.color_ramp.elements[1].position=0.7
    node_ramp.color_ramp.elements[1].color = (1,1,1,1)

    links.new(node_texture.outputs[0],node_ramp.inputs[0])
    links.new(node_ramp.outputs[0],bsdf.inputs[17])
    return mat
$\endgroup$
1
  • 1
    $\begingroup$ Are you trying to create a spiral transformation of a mesh? Textures could provide the spiral itself visually. You may want to show regular rectangular grid and the mesh transformed by a proportional edit rotation resulting in a spiral. I am not sure I understand why translation would be your goal. Since the question involves materials or textures you may want to specify whether the texture has a static spiral motif or you intend to create a uv map with a spiral motif. You may want to place a question mark on your question (???) Please show images if possible. $\endgroup$ Commented May 25, 2021 at 18:17

1 Answer 1

1
$\begingroup$

I was not able to apply the transformation

bpy.ops.transform.translate(value=(1.03353, 0.00369117, 0), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=True, use_proportional_edit=True, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)

to the uv-mesh. Blender only applies this transformation to the active element.

Instead, it is possible to rotate the mesh manually. To obtain the proportional rotation, I rotated the mesh depending on the radius of the mesh point.

import bpy
import math
import numpy as np
import random
import bpy
import mathutils
from mathutils import Vector,Quaternion

#make objects glow
bpy.context.scene.eevee.use_bloom = True
#make background black
bpy.data.worlds["World"].node_tree.nodes["Background"].inputs[0].default_value = (0, 0, 0, 1)



#delete all objects
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

#camera0
bpy.ops.object.camera_add(enter_editmode=False, align='VIEW', location=(20,0,0), rotation=(math.radians(90), math.radians(0), math.radians(90)))
camera = bpy.context.active_object

#sphere
bpy.ops.mesh.primitive_uv_sphere_add(segments = 30,ring_count=30,radius = 2, enter_editmode = False, location=(0,0,0))
galaxy = bpy.context.active_object
galaxy.scale[2]=0.1


mat = bpy.data.materials.new("GalaxyMaterial")

mat.use_nodes = True
node_tree = mat.node_tree
nodes = node_tree.nodes

output = nodes.get("Material Output")
bsdf = nodes.get("Principled BSDF") 

links =mat.node_tree.links

node_coord = nodes.new(type="ShaderNodeTexCoord")

node_texture = nodes.new(type='ShaderNodeTexNoise')

links.new(node_coord.outputs[2],node_texture.inputs[0])
node_texture.inputs[2].default_value=25
node_texture.inputs[3].default_value=5.3
node_texture.inputs[4].default_value=0.567
node_texture.inputs[5].default_value=1.1


node_ramp = nodes.new(type='ShaderNodeValToRGB')

node_ramp.color_ramp.elements[0].color = (0,0,0,1)
node_ramp.color_ramp.elements[0].position=0.45
node_ramp.color_ramp.elements[1].position=0.7
node_ramp.color_ramp.elements[1].color = (1,1,1,1)

links.new(node_texture.outputs[0],node_ramp.inputs[0])
links.new(node_ramp.outputs[0],bsdf.inputs[17])

def proportional_rotation(radius):
    return mathutils.Matrix.Rotation(math.radians(-200*radius), 4, 'Z')

# rotate vertices proportial to their distance from the origin
mesh = galaxy.data
for vert in mesh.vertices:
    r = math.sqrt(vert.co[0]*vert.co[0]+vert.co[1]*vert.co[1])
    vert.co = proportional_rotation(r) @ vert.co


galaxy.data.materials.append(mat)

The result looks like: enter image description here

$\endgroup$

You must log in to answer this question.

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