【blender开发】网格基础5:圆与圆柱

[sc name=”zhuanzai” author=”sinestesia” link=”https://sinestesia.co/blog/tutorials/python-tubes-cilinders/” ][/sc]

系列教程

1:生成2D 网格

2:立方体与矩阵 | Matrix函数

3:正二十面体与细分 | 黄金比例

4:圆角立方体

5:圆与圆柱

完整代码

import bpy
import bmesh
import math


# ------------------------------------------------------------------------------
# Utility Functions

def set_smooth(obj):
    """ 面平滑着色 """

    for face in obj.data.polygons:
        face.use_smooth = True


def object_from_data(data, name, scene, select=True):
    """ 创建网格对象 并连接场景 """

    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(data['verts'], data['edges'], data['faces'])

    obj = bpy.data.objects.new(name, mesh)
    scene.collection.objects.link(obj)

    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj

    mesh.update(calc_edges=True)
    mesh.validate(verbose=True)

    return obj


def recalculate_normals(mesh):
    """ 使网格的法线一致 """

    bm = bmesh.new()
    bm.from_mesh(mesh)

    bmesh.ops.recalc_face_normals(bm, faces=bm.faces)

    bm.to_mesh(mesh)
    bm.free()


# ------------------------------------------------------------------------------
# Geometry functions

def vertex_circle(segments, z):
    """ 返回环形顶点 """
    verts = []

    for i in range(segments):
        angle = (math.pi*2) * i / segments
        verts.append((math.cos(angle), math.sin(angle), z))

    return verts


def face(segments, i, row):
    """ 在圆柱上返回面 """

    if i == segments - 1:
        ring_start = segments * row
        base = segments * (row + 1)

        return (base - 1, ring_start, base, (base + segments) - 1)

    else:
        base = (segments * row) + i
        return (base, base + 1, base + segments + 1, base + segments)


def bottom_cap(verts, faces, segments, cap='NGON'):
    """ 用三角形制作底盖 """

    if cap == 'TRI':
        verts.append((0, 0, 0))
        center_vert = len(verts) - 1

        [faces.append((i, i+1, center_vert)) for i in range(segments - 1)]
        faces.append((segments - 1, 0, center_vert))

    elif cap == 'NGON':
        faces.append([i for i in range(segments)])

    else:
        print('[!] Passed wrong type to bottom cap')


def top_cap(verts, faces, segments, rows, cap='NGON'):
    """ 用三角形制作顶盖 """

    if cap == 'TRI':
        verts.append((0, 0, rows - 1))
        center_vert = len(verts) - 1
        base = segments * (rows - 1)

        [faces.append((base+i, base+i+1, center_vert))
                       for i in range(segments - 1)]

        faces.append((segments * rows - 1, base, center_vert))

    elif cap == 'NGON':
        base = (rows - 1) * segments
        faces.append([i + base for i in range(segments)])

    else:
        print('[!] Passed wrong type to top cap')


# ------------------------------------------------------------------------------
# 主函数

def make_circle(name, segments=32, fill=None):
    """ 制作一个圆 """

    data = {
            'verts': vertex_circle(segments, 0),
            'edges': [],
            'faces': [],
           }

    if fill:
        bottom_cap(data['verts'], data['faces'], segments, fill)
    else:
        data['edges'] = [(i, i+   1) for i in range(segments)]
        data['edges'].append((segments - 1, 0))

    scene = bpy.context.scene
    return object_from_data(data, name, scene)


def make_cylinder(name, segments=64, rows=4, cap=None):
    """ 制作一个圆柱体 """

    data = { 'verts': [], 'edges': [], 'faces': [] }

    for z in range(rows):
        data['verts'].extend(vertex_circle(segments, z))

    for i in range(segments):
        for row in range(0, rows - 1):
            data['faces'].append(face(segments, i, row))

    if cap:
        bottom_cap(data['verts'], data['faces'], segments, cap)
        top_cap(data['verts'], data['faces'], segments, rows, cap)


    scene = bpy.context.scene
    obj = object_from_data(data, name, scene)
    recalculate_normals(obj.data)
    set_smooth(obj)

    bevel = obj.modifiers.new('Bevel', 'BEVEL')
    bevel.limit_method = 'ANGLE'

    obj.modifiers.new('Edge Split', 'EDGE_SPLIT')

    return obj


# ------------------------------------------------------------------------------
# Main Code

# make_circle('Circle', 64)
make_cylinder('Cylinder', 128, 4, 'TRI')

 

给TA充电
共{{data.count}}人
人已充电
BlenderBlender开发

【Blender开发】使用PySide进行交互

2022-1-17 18:11:33

BlenderBlender开发

【Blender开发】UI:构建自己的UI | 基于BL库

2022-1-18 23:02:29

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
搜索