我是blender python的新手,我仔细阅读了IDE文档,但仍然无法解决两个问题:
我创建了一个参考对象(一个非常薄的平面,应该是一条线)
然后我复制了参考线,代码中称为LineRef,多次(移动到(0,0)后),每个新副本放置在一个假想圆的外围,与其他圆等距,并旋转,以便它们形成一个内接在圆中的多边形。它们是线0、线0、线1等等
然后,我给他们材料
我有两个问题:
当我创建完所有的“线”后,我创建的最后一条线和参考线似乎被交换了。我不知道我做错了什么
当我查看每一行的材质时,我可以看到原始的BSDF节点仍然存在。我怎样才能摆脱它
代码如下:
import bpy
from math import sin, cos, tau, sqrt
import os
os.system("cls")
showDebug = False # for debug: show points and line lengths arrays
showColMats = False # for debug: show colors and materials
emission_mat = []
lineNr = 0
mats = bpy.data.materials
points = []
numPoints = 7 # The number of points to be distributed equidistantly on the circumference of the circle of radius defined below
radius = 100 # The radius of the circle the points will sit on
# The consecutive values, from index 1, of the array below have the length of a side from a point to a point index away from it
sidesLen = []
sidesLen.append(0) # Array of sides lengths [0] has 0, see note 3 lines above
colors_and_strengths = [((1, 1, 1, 1), 50, "white"),
((1, 0, 0, 1), 50, "red"),
((0, 1, 0, 1), 50, "green"),
((0, 0, 1, 1), 50, "blue"),
((1, 1, 0, 1), 50, "yellow"),
((1, 0, 1, 1), 50, "purple"),
((.008, .008, .008, 1), 50, "gray") ]
##### REMOVE OLD LINES FUNCTION
def removeOldLines():
objs = bpy.data.objects
for obj in objs:
if obj.name != 'Camera' and obj.name != 'Arrow' and obj.name != 'Light':
bpy.data.objects.remove(obj, do_unlink=True)
##### END OF REMOVE OLD LINES FUNCTION
##### START OF PURGEOLDMATERIALS FUNCTION, FROM https://blenderartists.org/t/deleting-all-materials-in-script/594160/2
def purgeOldMaterials():
for mat in mats:
mats.remove(bpy.data.materials[0])
##### END OF PURGEOLDMATERIALS FUNCTION
##### START OF POPULATEPOINTSANDLINELENGTHS FUNCTION
def populatePointsAndLineLengths():
global radius
global sideLen
for i in range(numPoints):
points.append((round(radius * cos(i * tau/numPoints)), round(radius * sin(i * tau/numPoints)), 0))
if showDebug == True:
for i in range(len(points)):
print("I have points[", str(i), "]:", points[i])
# Build sidesLen array for EVEN numPoints
if numPoints % 2 == 0:
numPointsOver2 = int (numPoints/2)
# Fill from 0 to numPoints/2 excluded
for i in range(1, numPointsOver2):
sidesLen.append(round(sqrt((points[i][0] - points[0][0]) * (points[i][0] - points[0][0]) + (points[i][1] - points[0][1]) * (points[i][1] - points[0][1]))))
# Fill numPoints/2, the lone longest segment
sidesLen.append(round(sqrt((points[numPointsOver2][0] - points[0][0]) * (points[numPointsOver2][0] - points[0][0]) + (points[numPointsOver2][1] - points[0][1]) * (points[numPointsOver2][1] - points[0][1]))))
# Fill numPoints/2 + 1 to numPoints - 1
for i in range(numPointsOver2 + 1, numPoints - 0):
sidesLen.append(sidesLen[numPoints - i])
# END OF BUILD SIDES LENGTHS ARRAY FOR EVEN numPoints
# Build sidesLen array for ODD numPoints
if numPoints % 2 != 0:
numPointsOver2 = int (numPoints / 2)
# Fill from 0 to numPoints/2 INCLUDED
for i in range(1, numPointsOver2 + 1):
sidesLen.append(round(sqrt((points[i][0] - points[0][0]) * (points[i][0] - points[0][0]) + (points[i][1] - points[0][1]) * (points[i][1] - points[0][1]))))
# Fill numPoints/2 + 1 to numPoints - 1
for i in range(numPointsOver2 + 1, numPoints):
sidesLen.append(sidesLen[numPoints - i])
# END OF BUILD SIDES LENGTHS ARRAY FOR ODD numPoints
if showDebug == True:
for i in range(len(sidesLen)):
print("sidesLen[", str(i), "]:", sidesLen[i])
##### END OF POPULATEPOINTSANDLINELENGTHS FUNCTION
##### START OF createRefLine FUNCTION
def createRefLine():
bpy.ops.mesh.primitive_plane_add(enter_editmode=True, align='WORLD', location=(0, 0, 0), scale=(100, 100, 10))
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.transform.resize(value=(50, 0.9, 1))
bpy.ops.transform.translate(value=(50, 0, 0))
bpy.ops.object.editmode_toggle()
bpy.context.object.name="LineRef"
##### END OF createRefLine FUNCTION
##### CREATE SHADERS FUNCTION
def createShaders():
# EMISSION SHADER: CREATE AN EMISSION SHADER SO THAT WE CAN SEE THE LINE
# EMISSION SHADER: NEW SHADER
COLOR = 0
STRENGTH = 1
COLOR_NAME = 2
if showColMats == True:
print("------->I have the following colors:")
for i in range(len(colors_and_strengths)):
print("------------>", colors_and_strengths[i])
global emission_mat
nodes = []
material_output = []
node_emission = []
links = []
# create as many materials as we have colors
for col_or in range(len(colors_and_strengths)):
emission_mat.append(bpy.data.materials.new(name="Emission_" + colors_and_strengths[col_or][COLOR_NAME]))
emission_mat[col_or].use_nodes = True
nodes.append(emission_mat[col_or].node_tree.nodes)
material_output.append(nodes[col_or].get('Material Output'))
node_emission.append(nodes[col_or].new(type='ShaderNodeEmission'))
node_emission[col_or].inputs[0].default_value = colors_and_strengths[col_or][COLOR] # RGB + Alpha
node_emission[col_or].inputs[1].default_value = colors_and_strengths[col_or][STRENGTH] # strength
links.append(emission_mat[col_or].node_tree.links)
new_link = links[col_or].new(node_emission[col_or].outputs[0], material_output[col_or].inputs[0])
if showColMats == True:
for i in range(len(emission_mat)):
print("Material:", emission_mat[i])
##### EN OF CREATE SHADERS FUNCTION
##### START OF DUPANDMOVEANDROTATELINE FUNCTION
def dupAndMoveAndRotateLine(objectGiven, contextGiven, xGiven, yGiven, angleGiven, size):
#bpy.ops.object.delete(use_global=True, confirm=False)
global lineNr
objectGiven.duplicate_move()
bpy.context.object.name="Line_0_" + str(lineNr)
lineNr += 1
objectGiven.rotation_clear()
contextGiven.rotation_euler[2] = angleGiven
objectGiven.scale_clear()
bpy.ops.transform.resize(value=size)
contextGiven.location[0] = xGiven
contextGiven.location[1] = yGiven
##### END OF DUPANDMOVEANDROTATELINE FUNCTION
# LET'S HAVE FUN NOW!
purgeOldMaterials() # print("\n\n------->Calling purgeOldMaterials...")
removeOldLines() # print("------->Calling removeOldLines...")
populatePointsAndLineLengths() # print("------->Calling populatePointsAndLineLengths...")
createRefLine() # print("------->Calling createRefLine...")
createShaders() # print("------->Calling createShaders...")
bpy.data.objects['LineRef'].data.materials.append(emission_mat[0]) # ASSIGN EMISSION SHADER TO THE REFERENCE LINE..
# NOW WE HAVE A REFERENCE LINE WITH AN EMISSION SHADER, LET'S MOVE IT OUT OF THE WAY
bpy.ops.transform.translate(value=(-sidesLen[1] / 2, 0, 0)) # Move the reference line out of the way
bpy.ops.transform.resize(value=(2, 1, 1)) # Resize the reference line
# draw numPoints lines on periphery
for i in range(numPoints):
dupAndMoveAndRotateLine(bpy.ops.object, bpy.context.object, points[i][0], points[i][1], (i) * tau * (1 / numPoints) + (tau / 2) * (1 / 2 + 1/numPoints), (sidesLen[1] / 100, 1, 1))
# Apply materials to lines
for i in range(numPoints):
bpy.data.objects['Line_0_' + str(i)].data.materials.clear()
bpy.data.objects['Line_0_' + str(i)].data.materials.append(emission_mat[i % len(emission_mat) - 0])
目前没有回答
相关问题 更多 >
编程相关推荐