这不是我的工作,但我正在努力让它发挥作用。这是我在网上找到的一个脚本,用于生成 bianchi Pinkall 曲面,显然它曾经有效,但现在不起作用。如果有什么东西可以让它工作,那将是令人难以置信的,因为我正在尝试生成 3d 对象
import bpy
import math
from mathutils import Vector
import numpy
subDivIterations = 5
valminu=0
valmaxu=math.pi*2
valminv=0
valmaxv=math.pi*2
resolutionu=150
resolutionv=150
pasu = (valmaxu - valminu) / resolutionu
pasv = (valmaxv - valminv) / resolutionv
a=0.93 #rayon de la corale à tester sous : analyticphysics.com/Higher Dimensions/Interactive Bianchi-Pinkall Flat Tori.htm
n=3 #Nbre de sous rotation ou de pétaile
b=0.36 #rayon internet de la fleur
c=0
d=0
k=15
varu= valminu
varv= valminv
goldenRatio = (1 + math.sqrt(5)) / 2
def subdivide(triangles):
result = []
for color, A, B, C in triangles:
if color == 0:
# Subdivide red triangle
P = A + (B - A) / goldenRatio
result += [(0, C, P, B), (1, P, C, A)]
else:
# Subdivide blue triangle
Q = B + (A - B) / goldenRatio
R = B + (C - B) / goldenRatio
result += [(1, R, C, A), (1, Q, R, B), (0, R, Q, A)]
return result
# Create des tirangles du coquillage
# Create wheel of red triangles around the origin
#x = f(u,v) = u + uv2 – (1/3)u3, y = g(u,v) = v + u2v – (1/3)v3, z = h(u,v) = u2 – v2.
def createSurfaceBianchiPinkall():
triangles = []
for varu in numpy.arange(valminu, valmaxu, pasu):
for varv in numpy.arange(valminv, valmaxv, pasv):
gamma = a+b*math.sin(2*n*varv)
x = math.cos(varu+varv)*math.cos(gamma)
y = math.sin(varu+varv)*math.cos(gamma)
z = math.cos(varu-varv)*math.sin(gamma)
w = math.sin(varu-varv)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
A = Vector((x*r,y*r,z*r))
varva = varv + pasv
gamma = a+b*math.sin(2*n*varva)
x = math.cos(varu+varva)*math.cos(gamma)
y = math.sin(varu+varva)*math.cos(gamma)
z = math.cos(varu-varva)*math.sin(gamma)
w = math.sin(varu-varva)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
B = Vector((x*r,y*r,z*r))
varua = varu + pasu
gamma = a+b*math.sin(2*n*varva)
x = math.cos(varua+varva)*math.cos(gamma)
y = math.sin(varua+varva)*math.cos(gamma)
z = math.cos(varua-varva)*math.sin(gamma)
w = math.sin(varua-varva)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
C = Vector((x*r,y*r,z*r))
triangles.append((0, A, B, C))
gamma = a+b*math.sin(2*n*varv)
x = math.cos(varua+varv)*math.cos(gamma)
y = math.sin(varua+varv)*math.cos(gamma)
z = math.cos(varua-varv)*math.sin(gamma)
w = math.sin(varua-varv)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
D = Vector((x*r,y*r,z*r))
triangles.append((0, A, C, D))
return triangles
# Generate map of tiling
listTriangles = createSurfaceBianchiPinkall()
#for x in range(subDivIterations):
# listTriangles = subdivide(listTriangles)
# Construction du coquilage
# Construct the lists necessary for generation of geometry
listVertices = []
listFaces = []
for triangle in listTriangles:
# write the vertex coords to the list, and remember the vertex indices
# In Blender, the mesh data stores each vertex as a tuple of 3 floats.
newVertex1 = (triangle[1][0],triangle[1][1],triangle[1][2])
newVertex2 = (triangle[2][0],triangle[2][1],triangle[2][2])
newVertex3 = (triangle[3][0],triangle[3][1],triangle[3][2])
listVertices.append(newVertex1)
newVertex1_i = len(listVertices) - 1
listVertices.append(newVertex2)
newVertex2_i = len(listVertices) - 1
listVertices.append(newVertex3)
newVertex3_i = len(listVertices) - 1
# write to the list of edges
# Define the faces by index numbers. Each faces is defined by 4 consecutive integers.
# For triangles you need to repeat the first vertex also in the fourth position.
newFace = (newVertex1_i,newVertex2_i,newVertex3_i)
listFaces.append(newFace)
mesh = bpy.data.meshes.new("SurfaceBianchiPinkallMesh") # create a new mesh
ob = bpy.data.objects.new("SurfaceBianchiPinkall", mesh) # create an object with that mesh
ob.location = Vector((0,0,0)) #by.context.scene.cursor_location # position object at 3d-cursor
bpy.context.scene.objects.link(ob) # Link object to scene
# Fill the mesh with verts, edges, faces
mesh.from_pydata(listVertices,[],listFaces) # edges or faces should be [], or you ask for problems
mesh.validate(True)
#mesh.update(calc_edges=True) # Update mesh with new data
我尝试使用 VScode 查看 python 脚本,但我不了解 python,所以……这都是为了送给特别的人的礼物。
可能有很多原因导致问题,其中之一是您附加的代码不遵循正确的 python 缩进。如果我们修复了这个问题,我们可以继续进行真正的修改,这只是 Blender 2.8+ 重构的结果。
从Blender 2.8 集合变更日志我们了解到
图层和组已被集合取代。
对我们来说,这意味着您的第 121 行
bpy.context.scene.objects.link(ob)
现在会抛出 AttributeError: bpy_prop_collection: attribute "link" not found
,因为链接属性已按照 文档放置在
bpy.context.scene.objects
下。具体来说,这意味着您需要将第 121 行替换为
bpy.context.collection.objects.link(ob)
我们得到的下一个错误
TypeError: Mesh.validate(): required parameter "verbose" to be a keyword argument!
,这源自第124行,mesh.validate(True)
,问题非常简单,为了避免与clean_customdata
参数产生歧义,我们只需要指定我们正在提供详细信息,因此我们替换第124行与
mesh.validate(verbose=True)
我能够在 Blender 3.4 和 4.0 上验证这一点。
我已附上下面完整修改的代码(以及我重新创建的缩进)以及成功输出的屏幕截图。
import bpy
import math
from mathutils import Vector
import numpy
subDivIterations = 5
valminu=0
valmaxu=math.pi*2
valminv=0
valmaxv=math.pi*2
resolutionu=150
resolutionv=150
pasu = (valmaxu - valminu) / resolutionu
pasv = (valmaxv - valminv) / resolutionv
a=0.93 #rayon de la corale à tester sous : analyticphysics.com/Higher Dimensions/Interactive Bianchi-Pinkall Flat Tori.htm
n=3 #Nbre de sous rotation ou de pétaile
b=0.36 #rayon internet de la fleur
c=0
d=0
k=15
varu= valminu
varv= valminv
goldenRatio = (1 + math.sqrt(5)) / 2
def subdivide(triangles):
result = []
for color, A, B, C in triangles:
if color == 0:
# Subdivide red triangle
P = A + (B - A) / goldenRatio
result += [(0, C, P, B), (1, P, C, A)]
else:
# Subdivide blue triangle
Q = B + (A - B) / goldenRatio
R = B + (C - B) / goldenRatio
result += [(1, R, C, A), (1, Q, R, B), (0, R, Q, A)]
return result
# Create des tirangles du coquillage
# Create wheel of red triangles around the origin
#x = f(u,v) = u + uv2 – (1/3)u3, y = g(u,v) = v + u2v – (1/3)v3, z = h(u,v) = u2 – v2.
def createSurfaceBianchiPinkall():
triangles = []
for varu in numpy.arange(valminu, valmaxu, pasu):
for varv in numpy.arange(valminv, valmaxv, pasv):
gamma = a+b*math.sin(2*n*varv)
x = math.cos(varu+varv)*math.cos(gamma)
y = math.sin(varu+varv)*math.cos(gamma)
z = math.cos(varu-varv)*math.sin(gamma)
w = math.sin(varu-varv)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
A = Vector((x*r,y*r,z*r))
varva = varv + pasv
gamma = a+b*math.sin(2*n*varva)
x = math.cos(varu+varva)*math.cos(gamma)
y = math.sin(varu+varva)*math.cos(gamma)
z = math.cos(varu-varva)*math.sin(gamma)
w = math.sin(varu-varva)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
B = Vector((x*r,y*r,z*r))
varua = varu + pasu
gamma = a+b*math.sin(2*n*varva)
x = math.cos(varua+varva)*math.cos(gamma)
y = math.sin(varua+varva)*math.cos(gamma)
z = math.cos(varua-varva)*math.sin(gamma)
w = math.sin(varua-varva)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
C = Vector((x*r,y*r,z*r))
triangles.append((0, A, B, C))
gamma = a+b*math.sin(2*n*varv)
x = math.cos(varua+varv)*math.cos(gamma)
y = math.sin(varua+varv)*math.cos(gamma)
z = math.cos(varua-varv)*math.sin(gamma)
w = math.sin(varua-varv)*math.sin(gamma)
r = math.acos(w)/math.pi/math.sqrt(1-w*w);
D = Vector((x*r,y*r,z*r))
triangles.append((0, A, C, D))
return triangles
# Generate map of tiling
listTriangles = createSurfaceBianchiPinkall()
#for x in range(subDivIterations):
# listTriangles = subdivide(listTriangles)
# Construction du coquilage
# Construct the lists necessary for generation of geometry
listVertices = []
listFaces = []
for triangle in listTriangles:
# write the vertex coords to the list, and remember the vertex indices
# In Blender, the mesh data stores each vertex as a tuple of 3 floats.
newVertex1 = (triangle[1][0],triangle[1][1],triangle[1][2])
newVertex2 = (triangle[2][0],triangle[2][1],triangle[2][2])
newVertex3 = (triangle[3][0],triangle[3][1],triangle[3][2])
listVertices.append(newVertex1)
newVertex1_i = len(listVertices) - 1
listVertices.append(newVertex2)
newVertex2_i = len(listVertices) - 1
listVertices.append(newVertex3)
newVertex3_i = len(listVertices) - 1
# write to the list of edges
# Define the faces by index numbers. Each faces is defined by 4 consecutive integers.
# For triangles you need to repeat the first vertex also in the fourth position.
newFace = (newVertex1_i,newVertex2_i,newVertex3_i)
listFaces.append(newFace)
mesh = bpy.data.meshes.new("SurfaceBianchiPinkallMesh") # create a new mesh
ob = bpy.data.objects.new("SurfaceBianchiPinkall", mesh) # create an object with that mesh
ob.location = Vector((0,0,0)) #by.context.scene.cursor_location # position object at 3d-cursor
bpy.context.collection.objects.link(ob) # Link object to scene
# Fill the mesh with verts, edges, faces
mesh.from_pydata(listVertices,[],listFaces) # edges or faces should be [], or you ask for problems
mesh.validate(verbose=True)
#mesh.update(calc_edges=True) # Update mesh with new data