学习使用blender(BlenderPython开发简明教程)

Blender 是一个功能强大的开源建模平台,其功能可与 3D Studio Max 和 Maya 等专业级软件包相媲美。除了功能齐全的建模工具集之外,Blender 还具有非常强大的 Python API,它允许你创建脚本和附加组件。平台 Blender 用于建模的酷炫程度给我留下了深刻的印象……而且它是免费的!

学习使用blender(BlenderPython开发简明教程)(1)

1、Blender Python脚本环境

Blender 允许你更改视口布局以反映不同的工作方式。例如,你可能需要一组用于建模的窗口和一组用于渲染的不同窗口。脚本也是如此。Blender 带有预设的脚本布局,你可以对其进行自定义以满足你的编码需求。

Blender的界面包括:

  • 文本编辑器
  • Python 控制台
  • 信息窗口
  • Blender控制台

这是典型的脚本布局可能的样子……

学习使用blender(BlenderPython开发简明教程)(2)

2、Blender Python脚本设置

创建脚本并运行它非常容易。这一节将介绍基本工作流程以及一些在 Blender 中进入 API 的技巧。

导入 Blender Python API 是任何 Blender 脚本的第一步……你可以根据需要以标准方式导入其他库。

import bpy #Imports the Blender Python API import mathutils #Imports Blender vector math utilities import math #Imports the standard Python math library

print 命令会将结果打印到 Blender 控制台。你可以通过 Window 菜单或通过 Python 调用控制台来访问控制台。

#Set up some variables... standard Python rules apply... a = 'hello' b = ' world!' #Print the addition to the system console print (a b) #open the system console bpy.ops.wm.console_toggle()

学习使用blender(BlenderPython开发简明教程)(3)

Blender 提供了两种探索 API 的方式:Python 控制台和信息视口。不幸的是,Blender 没有内置在代码编辑器中的代码完成功能……

Blender 的“信息”视口将所有最近的 Blender 活动显示为可执行的 Python 命令。这对于使用建模方法对流程进行原型制作然后将它们组装成脚本非常方便。

这是在场景中放置一些对象后信息窗口返回的内容……

学习使用blender(BlenderPython开发简明教程)(4)

从上面选择的文本可以复制并粘贴到文本编辑器中。我们可以从命令中删除任何不需要的选项。该脚本将在场景中创建一个网格立方体。

import bpy #Imports the Blender Python API import mathutils #Imports Blender vector math utilities import math #Imports the standard Python math library # Create a mesh cube in the scene bpy.ops.mesh.primitive_cube_add(location=(0.936607, -0.484878, 1.66298))

学习使用blender(BlenderPython开发简明教程)(5)

我们可以用一些变量交换位置值,以便更好地控制位置……

x = 5 y = 5 z = 0 # Create a mesh cube in the scene bpy.ops.mesh.primitive_cube_add(location=(x, y, z))

学习使用blender(BlenderPython开发简明教程)(6)

…或者我们可以将命令放在 For 循环中以创建一行立方体…

for i in range (0, 5): x = i*3 y = 0 z = 0 # Create a mesh cube in the scene bpy.ops.mesh.primitive_cube_add(location=(x, y, z))

学习使用blender(BlenderPython开发简明教程)(7)

或者嵌套的 For 循环用于立方体网格!

for i in range (0, 10): for j in range (0, 10): x = i*3 y = j*3 z = 0 # Create a mesh cube in the scene bpy.ops.mesh.primitive_cube_add(location=(x, y, z))

学习使用blender(BlenderPython开发简明教程)(8)

3、Blender Python网格定义

了解如何定义和创建网格对于在 Blender 中编写几何脚本至关重要。该过程相当简单,需要用户定义以下网格属性:

  • 顶点(由 X、Y 和 Z 定义的点)
  • 边(由顶点索引定义的线框曲线)
  • 面(由顶点索引定义的 3D 表面)

在下面这个例子中,我们将定义一个简单的平面来演示顶点和面索引之间的关系。平面将由四个点组成。

首先我们定义顶点和面变量……这些被定义为数组。

import bpy #Define vertices, faces #The vertex array contains 4 items with X, Y, and Z definitions verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0)] # the faces array contains 1 item. # The number sequence refers to the vertex array items. # The order will determine how the face is constructed. faces = [(0,1,2,3)]

我们现在需要为网格和场景对象定义变量……

#Define mesh and object mymesh = bpy.data.meshes.new("Plane") #the mesh variable is then referenced by the object variable myobject = bpy.data.objects.new("Plane", mymesh)

我们现在来定义网格的创建位置。我们可以设置要在光标位置创建的网格……

#Set location and scene of object myobject.location = bpy.context.scene.cursor_location # the cursor location bpy.context.scene.objects.link(myobject) # linking the object to the scene

现在我们可以创建网格了……

#Create mesh # this method has an optional 'edge' array input. This is left as an empty array mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True) #so the edges display properly...

最终代码如下:

import bpy #Define vertices and faces verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0)] faces = [(0,1,2,3)] # Define mesh and object variables mymesh = bpy.data.meshes.new("Plane") myobject = bpy.data.objects.new("Plane", mymesh) #Set location and scene of object myobject.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(myobject) #Create mesh mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True)

学习使用blender(BlenderPython开发简明教程)(9)

在完成上面的平面之后,立方体并没有那么大的变化。关键是跟踪顶点顺序和面索引…

import bpy #Define vertices, faces, edges verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(0,0,5),(0,5,5),(5,5,5),(5,0,5)] faces = [(0,1,2,3), (4,5,6,7), (0,4,5,1), (1,5,6,2), (2,6,7,3), (3,7,4,0)] #Define mesh and object mesh = bpy.data.meshes.new("Cube") object = bpy.data.objects.new("Cube", mesh) #Set location and scene of object object.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(object) #Create mesh mesh.from_pydata(verts,[],faces) mesh.update(calc_edges=True)

学习使用blender(BlenderPython开发简明教程)(10)

下面这个金字塔演示了如何使用 3 个索引而不是 4 个索引来创建三角形……

import bpy #Define vertices, faces, edges verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(2.5,2.5,4.5)] faces = [(0,1,2,3), (0,4,1), (1,4,2), (2,4,3), (3,4,0)] #Define mesh and object mesh = bpy.data.meshes.new("Cube") object = bpy.data.objects.new("Cube", mesh) #Set location and scene of object object.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(object) #Create mesh mesh.from_pydata(verts,[],faces) mesh.update(calc_edges=True)

学习使用blender(BlenderPython开发简明教程)(11)

4、Blender Python修改器

修改器使我们可以访问一些强大的网格操作功能。此页面显示如何以编程方式将修改器应用于网格。

首先看看细分修改器。

以下代码生成一个立方体...

import bpy #Define vertices, faces, edges verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(0,0,5),(0,5,5),(5,5,5),(5,0,5)] faces = [(0,1,2,3), (7,6,5,4), (0,4,5,1), (1,5,6,2), (2,6,7,3), (3,7,4,0)] #Define mesh and object mymesh = bpy.data.meshes.new("Cube") myobject = bpy.data.objects.new("Cube", mymesh) #Set location and scene of object myobject.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(myobject) #Create mesh mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True)

学习使用blender(BlenderPython开发简明教程)(12)

我们可以使用以下方法将细分修改器应用于网格…

# subdivide modifier myobject.modifiers.new("subd", type='SUBSURF')

学习使用blender(BlenderPython开发简明教程)(13)

我们还可以增加可见细分的数量……

# Increase subdivisions myobject.modifiers['subd'].levels = 3

学习使用blender(BlenderPython开发简明教程)(14)

虽然与修改器没有真正的关系......我们也可以使用以下技术将顶点着色更改为“平滑”......

# show mesh as smooth mypolys = mymesh.polygons for p in mypolys: p.use_smooth = True

学习使用blender(BlenderPython开发简明教程)(15)

完整的代码如下:

import bpy #Define vertices, faces, edges verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(0,0,5),(0,5,5),(5,5,5),(5,0,5)] faces = [(0,1,2,3), (7,6,5,4), (0,4,5,1), (1,5,6,2), (2,6,7,3), (3,7,4,0)] #Define mesh and object mymesh = bpy.data.meshes.new("Cube") myobject = bpy.data.objects.new("Cube", mymesh) #Set location and scene of object myobject.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(myobject) #Create mesh mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True) # subdivide modifier myobject.modifiers.new("subd", type='SUBSURF') # Increase subdivisions myobject.modifiers['subd'].levels = 3 # show mesh as smooth mypolys = mymesh.polygons for p in mypolys: p.use_smooth = True

5、Blender Python数学网格

在掌握了使用顶点和面创建网格的基础知识之后,了解一些使用更有效的过程生成它们的技术非常重要。本页介绍了一些用于从数学方程绘制网格的代码。在此过程中,你可以看到如何使用变量和循环来组织顶点和面。

首先看波面。

学习使用blender(BlenderPython开发简明教程)(16)

这些变量对于创建波面以及让我们控制创建变化都是必不可少的。

# mesh arrays verts = [] # the vertex array faces = [] # the face array # mesh variables numX = 10 # number of quadrants in the x direction numY = 10 # number of quadrants in the y direction # wave variables freq = 1 # the wave frequency amp = 1 # the wave amplitude scale = 1 #the scale of the mesh

定义变量后,我们可以使用它们来控制 Wave 表面的参数方程。波面用参数形式定义:

  • x = i
  • y = j
  • z = Cos(i) Sin(j)

为了控制表面,我们可以使用我们定义的尺度、频率和幅度变量:

  • x =Scale* i
  • y =Scale* j
  • z =Scale* (Amplitude*Cos(i *Frequency) Amplitude*Sin(j *Frequency))

通过将 x、y 和 z 变量放入包含变量 i 和 j 的嵌套 For 循环中,我们可以绘制映射参数曲面的顶点网格。

在这个阶段,我们可以通过使用顶点数组和空面数组创建网格来验证点的绘制方式。

#fill verts array for i in range (0, numX): for j in range(0,numY): x = scale * i y = scale * j z = scale*((amp*math.cos(i*freq)) (amp*math.sin(j*freq))) vert = (x,y,z) verts.append(vert) #create mesh and object mesh = bpy.data.meshes.new("wave") object = bpy.data.objects.new("wave",mesh) #set mesh location object.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(object) #create mesh from python data mesh.from_pydata(verts,[],faces) mesh.update(calc_edges=True)

学习使用blender(BlenderPython开发简明教程)(17)

填充完顶点数组后,我们需要填充Face数组。面数组中的每个项目都应包含 4 个索引,这些索引引用顶点数组中的一个项目。

#fill faces array count = 0 for i in range (0, numY *(numX-1)): if count < numY-1: A = i # the first vertex B = i 1 # the second vertex C = (i numY) 1 # the third vertex D = (i numY) # the fourth vertex face = (A,B,C,D) faces.append(face) count = count 1 else: count = 0

学习使用blender(BlenderPython开发简明教程)(18)

完整的代码如下:

import bpy import math # mesh arrays verts = [] faces = [] # mesh variables numX = 10 numY = 10 # wave variables freq = 1 amp = 1 scale = 1 #fill verts array for i in range (0, numX): for j in range(0,numY): x = scale * i y = scale * j z = scale*((amp*math.cos(i*freq)) (amp*math.sin(j*freq))) vert = (x,y,z) verts.append(vert) #fill faces array count = 0 for i in range (0, numY *(numX-1)): if count < numY-1: A = i B = i 1 C = (i numY) 1 D = (i numY) face = (A,B,C,D) faces.append(face) count = count 1 else: count = 0 #create mesh and object mesh = bpy.data.meshes.new("wave") object = bpy.data.objects.new("wave",mesh) #set mesh location object.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(object) #create mesh from python data mesh.from_pydata(verts,[],faces) mesh.update(calc_edges=True)

学习使用blender(BlenderPython开发简明教程)(19)

6、Blender Python随机网格

如果正在为你的脚本寻找更多的意外发现,为什么不尝试一个随机变量呢?然而,正弦波表面是一种非常可预测的形式,我们可以通过在参数图中提供随机变量来创建一个不太可预测的结构。

关键是使用 import random 导入随机库。

我们将使用与波浪表面几乎相同的脚本。但是,我们将使用随机变量,而不是使用数学 Sin 运算来控制 Z 轴。

学习使用blender(BlenderPython开发简明教程)(20)

要访问随机值,首先需要导入 random 类:

import random

然后我们可以在顶点的 For 循环中调用一个随机值……

#fill verts array for i in range (0, numX): for j in range(0,numY): x = scale * i y = scale * j z = random.random()*amp vert = (x,y,z) verts.append(vert)

学习使用blender(BlenderPython开发简明教程)(21)

我们可以通过将随机值乘以 i 变量并调整幅度来为随机变化创建增量效果。

#fill verts array for i in range (0, numX): for j in range(0,numY): x = scale * i y = scale * j z = (i * random.random())*amp vert = (x,y,z) verts.append(vert)

学习使用blender(BlenderPython开发简明教程)(22)

我们的网格有点粗糙,但我们可以使用细分修改器轻松平滑它。我们可以使用以下代码调用修改器:

# subdivide modifier myobject.modifiers.new("subd", type='SUBSURF') myobject.modifiers['subd'].levels = 3 # this adjusts the subdivisions in view

学习使用blender(BlenderPython开发简明教程)(23)

最后,我们可以将网格显示为“平滑”面……

# show mesh as smooth mypolys = mymesh.polygons for p in mypolys: p.use_smooth = True

完整的代码如下:

import bpy import random # mesh arrays verts = [] faces = [] # mesh variables numX = 20 numY = 20 # wave variables amp = 0.5 scale = 1 #fill verts array for i in range (0, numX): for j in range(0,numY): x = scale * i y = scale * j z = (i*random.random())*amp vert = (x,y,z) verts.append(vert) #fill faces array count = 0 for i in range (0, numY *(numX-1)): if count < numY-1: A = i B = i 1 C = (i numY) 1 D = (i numY) face = (A,B,C,D) faces.append(face) count = count 1 else: count = 0 #create mesh and object mymesh = bpy.data.meshes.new("random mesh") myobject = bpy.data.objects.new("random mesh",mymesh) #set mesh location myobject.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(myobject) #create mesh from python data mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True) # subdivide modifier myobject.modifiers.new("subd", type='SUBSURF') myobject.modifiers['subd'].levels = 3 # show mesh as smooth mypolys = mymesh.polygons for p in mypolys: p.use_smooth = True

经过渲染......好了!

学习使用blender(BlenderPython开发简明教程)(24)

7、Blender Python三维超形

3D Supershape 一直是我最喜欢的数学定义。Supershapes 提供了高水平的形式变化。这个 Blender Python 实现遵循我为 The Proving Ground 为Grasshopper、Revit 和 Processing 等平台创建的先前版本。

学习使用blender(BlenderPython开发简明教程)(25)

代码如下:

import bpy import math # mesh arrays verts = [] faces = [] edges = [] #3D supershape parameters m = 14.23 a = -0.06 b = 2.78 n1 = 0.5 n2 = -.48 n3 = 1.5 scale = 3 Unum = 50 Vnum = 50 Uinc = math.pi / (Unum/2) Vinc = (math.pi/2)/(Vnum/2) #fill verts array theta = -math.pi for i in range (0, Unum 1): phi = -math.pi/2 r1 = 1/(((abs(math.cos(m*theta/4)/a))**n2 (abs(math.sin(m*theta/4)/b))**n3)**n1) for j in range(0,Vnum 1): r2 = 1/(((abs(math.cos(m*phi/4)/a))**n2 (abs(math.sin(m*phi/4)/b))**n3)**n1) x = scale * (r1 * math.cos(theta) * r2 * math.cos(phi)) y = scale * (r1 * math.sin(theta) * r2 * math.cos(phi)) z = scale * (r2 * math.sin(phi)) vert = (x,y,z) verts.append(vert) #increment phi phi = phi Vinc #increment theta theta = theta Uinc #fill faces array count = 0 for i in range (0, (Vnum 1) *(Unum)): if count < Vnum: A = i B = i 1 C = (i (Vnum 1)) 1 D = (i (Vnum 1)) face = (A,B,C,D) faces.append(face) count = count 1 else: count = 0 #create mesh and object mymesh = bpy.data.meshes.new("supershape") myobject = bpy.data.objects.new("supershape",mymesh) #set mesh location myobject.location = bpy.context.scene.cursor_location bpy.context.scene.objects.link(myobject) #create mesh from python data mymesh.from_pydata(verts,edges,faces) mymesh.update(calc_edges=True) #set the object to edit mode bpy.context.scene.objects.active = myobject bpy.ops.object.mode_set(mode='EDIT') # remove duplicate vertices bpy.ops.mesh.remove_doubles() # recalculate normals bpy.ops.mesh.normals_make_consistent(inside=False) bpy.ops.object.mode_set(mode='OBJECT') # subdivide modifier myobject.modifiers.new("subd", type='SUBSURF') myobject.modifiers['subd'].levels = 3 # show mesh as smooth mypolys = mymesh.polygons for p in mypolys: p.use_smooth = True

使用不同的参数:

#3D supershape parameters m = 14.13 a = -0.06 b = 2.78 n1 = -2 n2 = -.1 n3 = 1 scale = 3 Unum = 70 Vnum = 70 Uinc = math.pi / (Unum/2) Vinc = (math.pi/2)/(Vnum/2) #fill verts array theta = -math.pi for i in range (0, Unum 1): phi = -math.pi/2 r1 = 1/(((abs(math.cos(m*theta/4)/a))**n2 (abs(math.sin(m*theta/4)/b))**n3)**n1) for j in range(0,Vnum 1): r2 = 1/(((abs(math.cos(m*phi/4)/a))**n2 (abs(math.sin(m*phi/4)/b))**n3)**n1) x = scale * (r1 * math.cos(theta) * r2 * math.cos(phi)) y = scale * (r1 * math.sin(theta) * r2 * math.cos(phi)) z = scale * (r2 * math.sin(phi)) vert = (x,y,z) verts.append(vert) #increment phi phi = phi Vinc #increment theta theta = theta Uinc


原文链接:http://www.bimant.com/blog/blender-python-crash-course/

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页