Blender - bpy

Python kód futtatása Blenderben. Első lépések.

A Blender fóablak alatt fogjuk meg egérrel és húzzuk fel az alsó sávot. Ezzel megosztjuk a képernyőt.

A sáv bal sarkába kattintva tudunk ablaknézetet váltani.

  • 3D Viewport: induláskor ez a főablak
  • Outliner: induláskor ez a jobb felső ablak, ahol az objektumok neve szerepel
  • Properties: induláskor a jobb alsó ablak, itt tudunk Modifier-eket futtatni.
  • Text editor: itt írjuk a Python kódot (+New) megnyomásával.

Az alsó sávot állítsuk át text editor nézetre és nyomjuk meg a +New gombot (középen)!

A főmenü Window menüpontjában a Toggle System Console bekapcsolja a rendszerkonzolt, ami a Python Idle Shell ablakához hasonlóan kiír, beolvas és hibaüzeneteket jelenít meg.

Írjuk be a print("Szia") utasítást és a play gomb megnyomásával futtassuk a kódot! A System Console-ban megjelenik a Szia felirat.

Egyszerű Blender kód: Kocka létrehozása
import bpy

bpy.ops.mesh.primitive_cube_add()
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 3))

A zárójelben megadhatjuk a location=[0,0,0] és rotation=[0,0,0] paramétereket, de dimenzion-t és nevet nem.

import bpy

bpy.ops.mesh.primitive_cube_add()
obj = bpy.context.active_object
obj.location = (0, 0, 2)
obj.dimensions = (100, 50, 2)
obj.name = "kocka"

Saját függvénykönyvtár importálása

FONTOS: másoljuk be abba a mappába a blenderalap.py fájlt, amiben elmentjük a belnder fájlokat! A blender fájlt munka előtt mentsük el abba a mappába, ahol a blender.py fájl is található!

Írjuk be a kódba az alábbi utasításokat!

         
1import bpy
2import math
3import random
4
5import sys
6import os
7blend_dir = os.path.dirname(bpy.data.filepath)
8if blend_dir not in sys.path:
9    sys.path.append(blend_dir)
10
11from blenderalap import *
A teljes blenderalap.py fájl
         
1import bpy
2import math
3import random
4
5 # -- reset -----------------------------------------
6def takarit():
7 # bpy.ops.object.select_all(action='SELECT')
8    for o in bpy.context.scene.objects:
9        o.hide_set(False)
10        o.select_set(True)
11        if o.name=="_padlo":
12            o.select_set(False)
13    bpy.ops.object.delete()
14
15    for coll in list(bpy.data.collections):
16        if coll.users == 0:
17            bpy.data.collections.remove(coll)
18
19 # -- objektumok kezelése ----------------------------
20def new_collection(name):
21    coll = bpy.data.collections.new(name)
22    bpy.context.scene.collection.children.link(coll) # Add collection to Scene Collection
23
24def exists_collection(name):
25    return any(coll.name == name for coll in bpy.data.collections)
26
27def exists_object(name):
28    return any(obj.name == name for obj in bpy.context.scene.objects)
29
30def move_object(obj=None, name=None, coll=None):
31    if not obj and name:
32        obj = bpy.context.scene.objects.get(name)
33    if not obj:
34        return None
35    for c in list(obj.users_collection):
36        c.objects.unlink(obj)
37    if coll is None:
38        bpy.context.scene.collection.objects.link(obj)
39    else:
40        col = bpy.data.collections.get(coll)
41        if col:
42            col.objects.link(obj)
43        else:
44            bpy.context.scene.collection.objects.link(obj)
45    return obj
46
47def delete_object(name):
48    obj = bpy.context.scene.objects.get(name)
49    if obj is None:
50        return False
51    bpy.context.view_layer.objects.active = obj
52    obj.select_set(True)
53    bpy.ops.object.delete()
54    return True
55
56def apply_scale(obj):
57    bpy.context.view_layer.objects.active = obj
58    obj.select_set(True)
59    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
60    obj.select_set(False)
61
62def mod_bevel(name, r=0.5, segments=7, angle=40, apply=True):
63    obj = bpy.context.scene.objects.get(name)
64    if not obj:
65        return None
66    bev = obj.modifiers.new(name="Bevel", type='BEVEL')
67    bev.width = r
68    bev.segments = segments
69    bev.profile = 0.5
70    bev.limit_method = 'ANGLE'
71    bev.angle_limit = math.radians(angle)
72    if apply:
73        bpy.context.view_layer.objects.active = obj
74        obj.select_set(True)
75        bpy.ops.object.modifier_apply(modifier=bev.name)
76        obj.select_set(False)
77    return obj
78
79def mod_boolean(mitS, mivelS, operation="DIFFERENCE", operand_type="OBJECT", apply=False):
80    if exists_collection(mivelS):
81        operand_type="COLLECTION"
82    mit = bpy.context.scene.objects.get(mitS)
83    bool1 = mit.modifiers.new(type="BOOLEAN", name="bool")
84    bool1.operation = operation # ["INTERSECT", "UNION", "DIFFERENCE"]
85    bool1.operand_type=operand_type
86    if operand_type=="OBJECT":
87        mivel = bpy.context.scene.objects.get(mivelS)
88        bool1.object = mivel
89        mivel.hide_set(True)
90        mit.select_set(False)
91    if operand_type=="COLLECTION":
92        mivel = bpy.data.collections.get(mivelS)
93        bool1.collection = mivel
94        bpy.context.view_layer.layer_collection.children.get(mivelS).hide_viewport = True # hide locally : eye icon
95    if apply:
96        bpy.context.view_layer.objects.active = mit
97        mit.select_set(True)
98        bpy.ops.object.modifier_apply(modifier=bool1.name)
99        mit.select_set(False)
100
101def add_mesh(verts=None, edges=None, faces=None, D=None, L=None, R=None, name="Mesh", coll=None, talajra=False):
102    if verts is None:
103        verts = [(-0.5, -0.5, -0.5), ( 0.5, -0.5, -0.5), ( 0.5,  0.5, -0.5), (-0.5,  0.5, -0.5),
104         (-0.5, -0.5,  0.5), ( 0.5, -0.5,  0.5), ( 0.5,  0.5,  0.5), (-0.5,  0.5,  0.5)]
105    if edges is None:
106        edges = []
107    if faces is None:
108        faces = [(1,0,3,2), (4,5,6,7), (0,1,5,4), (1,2,6,5), (2,3,7,6), (3,0,4,7)]
109    mesh = bpy.data.meshes.new(name)
110    mesh.from_pydata(verts, edges, faces)
111    mesh.update()
112    obj = bpy.data.objects.new(name, mesh)
113    obj.name=name
114    if D is None:
115        dimensions = [2,2,2]
116    else:
117        dimensions = list(D)
118    obj.scale = tuple(dimensions)
119    if L is None:
120        location = [0,0,0]
121    else:
122        location = list(L)
123    if talajra:
124        location[2] = location[2] + dimensions[2]/2
125    obj.location = location
126    if R is not None:
127        obj.rotation_euler = tuple(math.radians(a) for a in R)
128    move_object(obj=obj, coll=coll)
129    apply_scale(obj)
130    return obj
131 # --------------------------------------------------------------------------------------------------------
132def tegla(D=None, L=None, R=None, coll=None, name="Tegla", talajra=False):
133    return add_mesh(D=D, L=L, R=R, name=name, coll=coll, talajra=talajra)
134 # --------------------------------------------------------------------------------------------------------
135def hengeres(r=None, r2=None, m=None, a=None, n=32, D=None, L=None, R=None, coll=None, name="Hengeres", talajra=False, rnorm=None):
136    rx = 0.5
137    ry = 0.5
138    ma=1
139    if r is None:
140        r = 1
141    if r2 is None:
142        r2 = r
143    if n<3:
144        n=3
145    alfa = math.pi/n
146    if a is not None:
147        r = r*a/2/math.sin(alfa)
148        r2 = r2*a/2/math.sin(alfa)
149    if rnorm is not None and rnorm>0:
150        xk = yk = float("inf")
151        xn = yn = float("-inf")
152        for i in range(n):
153            angle = alfa + 2*math.pi*i/n
154            x = math.cos(angle) * rx
155            y = math.sin(angle) * ry
156            xk=min(xk,x)
157            xn=max(xn,x)
158            yk=min(yk,y)
159            yn=max(yn,y)
160        if rnorm==1:
161            rx=rx/max(xn-xk, yn-yk)
162            ry=ry/max(xn-xk, yn-yk)
163        elif rnorm>1:
164            rx=rx/(xn-xk)
165            ry=ry/(yn-yk)
166    verts = []
167    for i in range(n):
168        angle = alfa + 2*math.pi*i/n
169        x = math.cos(angle) * rx
170        y = math.sin(angle) * ry
171        verts.append((x, y, -ma/2)) # alja
172    if r2>0:
173        for i in range(n):
174            angle = alfa + 2*math.pi*i/n
175            x = math.cos(angle) * rx * r2/r
176            y = math.sin(angle) * ry * r2/r
177            verts.append((x, y,  ma/2)) # teteje
178    else:
179        verts.append((0, 0,  ma/2)) # teteje
180
181    faces = []
182    alja=[]
183    teteje=[]
184    for i in range(0,n):
185        j = (i-1) % n
186        if r2>0:
187            faces.append((j, i, n+i, n+j))
188        else:
189            faces.append((j, i, n))
190        alja.append(n-1-i) # i | n-1-i
191        teteje.append(n+i) # n+i | 2*n-1-i :: (2n-1)-0...(2n-1)-(n-1)
192    faces.append(tuple(alja)) # alja
193    if r2>0:
194        faces.append(tuple(teteje)) # teteje
195    if D is None:
196        D = [1,1,1]
197    else:
198        D = list(D)
199    if r is not None:
200        D[0]=r*2
201        D[1]=r*2
202    if m is not None:
203        D[2]=m
204    return add_mesh(verts=verts, faces=faces, D=D, L=L, R=R, coll=coll, name=name, talajra=talajra)
205
206 # --------------------------------------------------------------------------------------------------------
207def henger(r=None, r2=None, m=None, n=64, D=None, L=None, R=None, coll=None, name="Henger", talajra=False, rnorm=1):
208    hengeres(r=r, r2=r2, m=m, a=None, n=n, D=D, L=L, R=R, coll=coll, name=name, talajra=talajra, rnorm=rnorm)
209 # --------------------------------------------------------------------------------------------------------
210def kup(r=None, r2=0, m=None, n=64, D=None, L=None, R=None, coll=None, name="kup", talajra=False, rnorm=1):
211    hengeres(r=r, r2=r2, m=m, a=None, n=n, D=D, L=L, R=R, coll=coll, name=name, talajra=talajra, rnorm=rnorm)
212 # --------------------------------------------------------------------------------------------------------
213def hasab(r=None, r2=None, m=None, a=None, n=3, D=None, L=None, R=None, coll=None, name="Hasab", talajra=False, rnorm=0):
214    hengeres(r=r, r2=r2, m=m, a=a, n=n, D=D, L=L, R=R, coll=coll, name=name, talajra=talajra, rnorm=rnorm)
215 # --------------------------------------------------------------------------------------------------------
216def gula(r=None, r2=0, m=None, a=None, n=3, D=None, L=None, R=None, coll=None, name="gula", talajra=False, rnorm=0):
217    hengeres(r=r, r2=r2, m=m, a=a, n=n, D=D, L=L, R=R, coll=coll, name=name, talajra=talajra, rnorm=rnorm)
218 # --------------------------------------------------------------------------------------------------------
219def gyuru(r=None, r2=None, m=None, n=64, v=0.2, D=None, L=None, R=None, coll=None, name="Gyuru", talajra=False, rnorm=1):
220    hengeres(r=r, r2=r2, m=m, a=None, n=n, D=D, L=L, R=R, coll=coll, name=name, talajra=talajra, rnorm=rnorm)
221    if r is not None:
222        r=r-v
223    if r2 is not None:
224        r2=r2-v
225    if D is not None:
226        D=[D[0]-2*v, D[1]-2*v, D[2]]
227    hengeres(r=r, r2=r2, m=m, a=None, n=n, D=D, L=L, R=R, coll=coll, name=name+"_kivon", talajra=talajra, rnorm=rnorm)
228    mod_boolean(name, name+"_kivon", apply=True)
229 # --------------------------------------------------------------------------------------------------------
230 # --------------------------------------------------------------------------------------------------------
231 # --------------------------------------------------------------------------------------------------------
232 # --------------------------------------------------------------------------------------------------------
233takarit()
234 # --------------------------------------------------------------------------------------------------------
235 # --- START ----------------------------------------------------------------------------------------------
236 # --------------------------------------------------------------------------------------------------------
237a=120
238b=60
239m=70
240v=2
241lv=10
242lx = a/2-lv
243ly = b/2-lv
244
245tegla(D=[a,b,v], L=[0,0,m-v],talajra=1, name="asztallap", coll="Collection")
246mod_bevel("asztallap")
247
248tegla(D=[lv,lv,m-v], L=[ lx, ly,0],talajra=1, name="lab1", coll="Collection")
249tegla(D=[lv,lv,m-v], L=[-lx, ly,0],talajra=1, name="lab2", coll="Collection")
250tegla(D=[lv,lv,m-v], L=[-lx,-ly,0],talajra=1, name="lab3", coll="Collection")
251tegla(D=[lv,lv,m-v], L=[ lx,-ly,0],talajra=1, name="lab4", coll="Collection")
252
253tegla(D=[2*lx-lv, v, lv], L=[ 0, ly, m-lv-v], talajra=1, name="fx1", coll="Collection")
254tegla(D=[2*lx-lv, v, lv], L=[ 0,-ly, m-lv-v], talajra=1, name="fx2", coll="Collection")
255tegla(D=[v, 2*ly-lv, lv], L=[ lx, 0, m-lv-v], talajra=1, name="fy1", coll="Collection")
256tegla(D=[v, 2*ly-lv, lv], L=[-lx, 0, m-lv-v], talajra=1, name="fy2", coll="Collection")
257
258tegla(D=[2*lx-lv, v, lv], L=[ 0, ly, 2*lv], talajra=1, name="ax1", coll="Collection")
259tegla(D=[2*lx-lv, v, lv], L=[ 0,-ly, 2*lv], talajra=1, name="ax2", coll="Collection")
260tegla(D=[v, 2*ly-lv, lv], L=[ lx, 0, 2*lv], talajra=1, name="ay1", coll="Collection")
261tegla(D=[v, 2*ly-lv, lv], L=[-lx, 0, 2*lv], talajra=1, name="ay2", coll="Collection")