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")