Blender程序化建模简明教程【PCG】
Blender 是一个功能强大的开源建模平台,其功能可与 3D Studio Max 和 Maya 等专业级软件包相媲美。除了功能齐全的建模工具集之外,Blender 还具有非常强大的 Python API,它允许你创建脚本和附加组件。平台 Blender 用于建模的酷炫程度给我留下了深刻的印象……而且它是免费的!
1、Blender Python脚本环境
Blender 允许你更改视口布局以反映不同的工作方式。例如,你可能需要一组用于建模的窗口和一组用于渲染的不同窗口。脚本也是如此。Blender 带有预设的脚本布局,你可以对其进行自定义以满足你的编码需求。
Blender的界面包括:
- 文本编辑器
- Python 控制台
- 信息窗口
- Blender控制台
这是典型的脚本布局可能的样子……
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 提供了两种探索 API 的方式:Python 控制台和信息视口。不幸的是,Blender 没有内置在代码编辑器中的代码完成功能……
Blender 的“信息”视口将所有最近的 Blender 活动显示为可执行的 Python 命令。这对于使用建模方法对流程进行原型制作然后将它们组装成脚本非常方便。
这是在场景中放置一些对象后信息窗口返回的内容……
从上面选择的文本可以复制并粘贴到文本编辑器中。我们可以从命令中删除任何不需要的选项。该脚本将在场景中创建一个网格立方体。
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))
我们可以用一些变量交换位置值,以便更好地控制位置……
x = 5
y = 5
z = 0# Create a mesh cube in the scene
bpy.ops.mesh.primitive_cube_add(location=(x, y, z))
…或者我们可以将命令放在 For 循环中以创建一行立方体…
for i in range (0, 5):x = i*3y = 0z = 0# Create a mesh cube in the scenebpy.ops.mesh.primitive_cube_add(location=(x, y, z))
或者嵌套的 For 循环用于立方体网格!
for i in range (0, 10):for j in range (0, 10):x = i*3y = j*3z = 0# Create a mesh cube in the scenebpy.ops.mesh.primitive_cube_add(location=(x, y, z))
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)
在完成上面的平面之后,立方体并没有那么大的变化。关键是跟踪顶点顺序和面索引…
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)
下面这个金字塔演示了如何使用 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)
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)
我们可以使用以下方法将细分修改器应用于网格…
# 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
完整的代码如下:
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数学网格
在掌握了使用顶点和面创建网格的基础知识之后,了解一些使用更有效的过程生成它们的技术非常重要。本页介绍了一些用于从数学方程绘制网格的代码。在此过程中,你可以看到如何使用变量和循环来组织顶点和面。
首先看波面。
这些变量对于创建波面以及让我们控制创建变化都是必不可少的。
# 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) +AmplitudeSin(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 * iy = scale * jz = 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)
填充完顶点数组后,我们需要填充Face数组。面数组中的每个项目都应包含 4 个索引,这些索引引用顶点数组中的一个项目。
#fill faces array
count = 0
for i in range (0, numY *(numX-1)):if count < numY-1:A = i # the first vertexB = i+1 # the second vertexC = (i+numY)+1 # the third vertexD = (i+numY) # the fourth vertexface = (A,B,C,D)faces.append(face)count = count + 1else:count = 0
完整的代码如下:
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 * iy = scale * jz = 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 = iB = i+1C = (i+numY)+1D = (i+numY)face = (A,B,C,D)faces.append(face)count = count + 1else: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)
6、Blender Python随机网格
如果正在为你的脚本寻找更多的意外发现,为什么不尝试一个随机变量呢?然而,正弦波表面是一种非常可预测的形式,我们可以通过在参数图中提供随机变量来创建一个不太可预测的结构。
关键是使用 import random
导入随机库。
我们将使用与波浪表面几乎相同的脚本。但是,我们将使用随机变量,而不是使用数学 Sin 运算来控制 Z 轴。
要访问随机值,首先需要导入 random 类:
import random
然后我们可以在顶点的 For 循环中调用一个随机值……
#fill verts array
for i in range (0, numX):for j in range(0,numY):x = scale * iy = scale * jz = random.random()*ampvert = (x,y,z) verts.append(vert)
我们可以通过将随机值乘以 i 变量并调整幅度来为随机变化创建增量效果。
#fill verts array
for i in range (0, numX):for j in range(0,numY):x = scale * iy = scale * jz = (i * random.random())*ampvert = (x,y,z) verts.append(vert)
我们的网格有点粗糙,但我们可以使用细分修改器轻松平滑它。我们可以使用以下代码调用修改器:
# subdivide modifier
myobject.modifiers.new("subd", type='SUBSURF')
myobject.modifiers['subd'].levels = 3 # this adjusts the subdivisions in view
最后,我们可以将网格显示为“平滑”面……
# 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 * iy = scale * jz = (i*random.random())*ampvert = (x,y,z) verts.append(vert)#fill faces array
count = 0
for i in range (0, numY *(numX-1)):if count < numY-1:A = iB = i+1C = (i+numY)+1D = (i+numY)face = (A,B,C,D)faces.append(face)count = count + 1else: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
经过渲染…好了!
7、 Blender Python三维超形
3D Supershape 一直是我最喜欢的数学定义。Supershapes 提供了高水平的形式变化。这个 Blender Python 实现遵循我为 The Proving Ground 为Grasshopper、Revit 和 Processing 等平台创建的先前版本。
代码如下:
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.5scale = 3Unum = 50
Vnum = 50Uinc = 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/2r1 = 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 phiphi = phi + Vinc#increment thetatheta = theta + Uinc#fill faces array
count = 0
for i in range (0, (Vnum + 1) *(Unum)):if count < Vnum:A = iB = i+1C = (i+(Vnum+1))+1D = (i+(Vnum+1))face = (A,B,C,D)faces.append(face)count = count + 1else: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 = 1scale = 3Unum = 70
Vnum = 70Uinc = 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/2r1 = 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 phiphi = phi + Vinc#increment thetatheta = theta + Uinc
原文链接:Blender Python开发入门 — BimAnt
Blender程序化建模简明教程【PCG】相关推荐
- 数学建模层次分析法例题及答案_【热门推荐】影响力意志力创新力、数学建模简明教程...
<影响力•意志力•创新力> 索书号:B848.4-49/1028 作者:邢群麟编著 出版社:浙江工商大学出版社,2018 馆藏地:新馆304室 简介:本书在总结众多成功人士经验的基础上, ...
- 《数学建模简明教程--基于python》学习笔记-第四章-微分方程-课后习题解答
文章目录 ⭐️0.准备工作⭐️
- 《数学建模简明教程--基于python》学习笔记-第二章-绘图与解方程组-课后习题解答
文章目录 准备工作 01 绘制双曲函数图像 02 绘制伽马函数图像 03 单个窗口绘制二次函数(k=1,2,...,6) 04 根据不同K值绘制子图 05 绘制二次曲面 05-1 绘制单叶双曲面 05 ...
- blender硬表面建模渲染终极教程
blender硬表面建模渲染终极教程 Gumroad - The ULTIMATE Guide to Hard Ops and Boxcutter Gumroad-硬操作和切箱机的终极指南 教程大小 ...
- UML精粹--标准对象建模语言简明教程
今天借了一本<UML精粹--标准对象建模语言简明教程>(Uml Distilled: A Brief Guide to the Standard Object Modeling Langu ...
- Blender赛车动画制作学习教程 Learn Race Car Animation with Blender
使用Blender 2.93创建您自己的惊人汽车动画 你会学到什么 Blender的界面和导航 建模 UV制图 材料 动画 照明设备 渲染 合成 要求 下载并安装Blender.免费下载和免费用于任何 ...
- Blender三维建模和动画风格化的东方场景视频教程
Blender三维建模和动画风格化的东方场景-Blender 3D Modelling & Animating A Stylized Oriental Scene Blender三维建模和动画 ...
- Blender基础入门学习教程 Learning Blender from Scratch
Blender基础入门学习教程 Learning Blender from Scratch 流派:电子学习| MP4 |视频:h264,1280×720 |音频:aac,48000 Hz 语言:英语+ ...
- lol模型导入ue4_Houdini amp; UE4 程序化建模——石头(一)基础工作流
导言 最近程序化建模的风气在国内兴起,建立好程序化建模流程,通过调参就可以生成丰富的美术资源.可以程序化建模的内容有很多,国外的程序化曼哈顿.林中小屋等都是很好的例子,所有带有规律的模型都可以程序化来 ...
- 【软考 系统架构设计师 简明教程】简介与目录
为了不辜负已经订阅了专栏的同学们的信任,所以本专栏不会有任何的优惠活动. 另外,当订阅人数每次达到2n(n>2)2^n(n>2)2n(n>2)时,订阅价格将会上涨10元. 所以,当下 ...
最新文章
- [case20]聊聊rest api设计
- java自定义日志级别_自定义log4j日志级别
- CSS DIV 居中
- 【小白学习C++ 教程】七、在C++指针声明和指针相关概念
- ueditor 编辑html文件名,UEditor编辑器自定义上传图片或文件路径的修改方法,ueditor修改方法...
- Oracle 2021年度安全警报: Critical Patch Update 发布8个数据库警告
- update set操作 根据变量选择colum
- 《美团机器学习实践》—— 读后总结
- 小米6刷peixl安卓8详细教程
- Nginx-反向代理
- 最优控制理论 八、CasADi求解路径约束轨迹优化的多重打靶法
- 微信里文件小程序导不出来_如何把小程序保存为文件 微信小程序导出文件
- 汇编c语言基础教程编程达人,编程达人 《汇编、C语言基础教程》第一章 进制1.6 逻辑运算(连载)...
- 将C语言的字符串转为OC的字符串
- 《微积分:一元函数微分学》——狄利克雷函数
- 不等式解集怎么取_口诀巧取不等式组的解集
- html表白程序源码_表白程序源码html_程序员表白代码html
- 汽车变速器(自动挡)英文缩写
- 一文搞懂什么是前端渲染和后端渲染以及两者的区别
- 嵌入式新闻早班车-第13期