procfunc 0.30.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- procfunc/__init__.py +87 -0
- procfunc/color.py +57 -0
- procfunc/compute_graph/__init__.py +28 -0
- procfunc/compute_graph/compute_graph.py +115 -0
- procfunc/compute_graph/node.py +200 -0
- procfunc/compute_graph/operators_info.py +92 -0
- procfunc/compute_graph/proxy.py +173 -0
- procfunc/compute_graph/util.py +282 -0
- procfunc/context.py +115 -0
- procfunc/control.py +174 -0
- procfunc/nodes/__init__.py +66 -0
- procfunc/nodes/bindings_util.py +196 -0
- procfunc/nodes/bpy_node_info.py +280 -0
- procfunc/nodes/compositor.py +2242 -0
- procfunc/nodes/execute/construct_nodes.py +571 -0
- procfunc/nodes/execute/construct_special_cases.py +246 -0
- procfunc/nodes/execute/execute.py +548 -0
- procfunc/nodes/execute/infer_runtime_data_type.py +195 -0
- procfunc/nodes/execute/util.py +247 -0
- procfunc/nodes/func.py +1417 -0
- procfunc/nodes/geo.py +4240 -0
- procfunc/nodes/manifest.json +8769 -0
- procfunc/nodes/math.py +644 -0
- procfunc/nodes/node_function.py +160 -0
- procfunc/nodes/shader.py +2359 -0
- procfunc/nodes/types.py +347 -0
- procfunc/ops/__init__.py +35 -0
- procfunc/ops/_util.py +275 -0
- procfunc/ops/addons.py +59 -0
- procfunc/ops/attr.py +426 -0
- procfunc/ops/collection.py +90 -0
- procfunc/ops/curve.py +18 -0
- procfunc/ops/file.py +126 -0
- procfunc/ops/manifest.json +39149 -0
- procfunc/ops/mesh.py +1510 -0
- procfunc/ops/modifier.py +603 -0
- procfunc/ops/object.py +258 -0
- procfunc/ops/primitives/__init__.py +31 -0
- procfunc/ops/primitives/camera.py +45 -0
- procfunc/ops/primitives/curve.py +71 -0
- procfunc/ops/primitives/light.py +114 -0
- procfunc/ops/primitives/mesh.py +358 -0
- procfunc/ops/uv.py +271 -0
- procfunc/random.py +247 -0
- procfunc/tracer/__init__.py +43 -0
- procfunc/tracer/decorator.py +121 -0
- procfunc/tracer/patch.py +494 -0
- procfunc/tracer/proxy.py +127 -0
- procfunc/tracer/trace.py +222 -0
- procfunc/transforms/__init__.py +49 -0
- procfunc/transforms/cleanup.py +214 -0
- procfunc/transforms/convert.py +20 -0
- procfunc/transforms/distribution.py +191 -0
- procfunc/transforms/extract_materials.py +116 -0
- procfunc/transforms/infer_distribution.py +326 -0
- procfunc/transforms/parameters.py +15 -0
- procfunc/transforms/util.py +35 -0
- procfunc/transpiler/__init__.py +24 -0
- procfunc/transpiler/bpy_to_computegraph.py +1348 -0
- procfunc/transpiler/codegen.py +919 -0
- procfunc/transpiler/identifiers.py +595 -0
- procfunc/transpiler/main.py +299 -0
- procfunc/types.py +380 -0
- procfunc/util/__init__.py +0 -0
- procfunc/util/bpy_info.py +145 -0
- procfunc/util/camera.py +0 -0
- procfunc/util/keyframe.py +70 -0
- procfunc/util/log.py +96 -0
- procfunc/util/manifest.py +121 -0
- procfunc/util/pytree.py +343 -0
- procfunc/util/teardown.py +37 -0
- procfunc-0.30.0.dist-info/METADATA +120 -0
- procfunc-0.30.0.dist-info/RECORD +76 -0
- procfunc-0.30.0.dist-info/WHEEL +5 -0
- procfunc-0.30.0.dist-info/licenses/LICENSE.md +11 -0
- procfunc-0.30.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import bpy
|
|
4
|
+
import numpy as np
|
|
5
|
+
from mathutils import Euler, Vector
|
|
6
|
+
|
|
7
|
+
from procfunc import types as t
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def mesh_single_vertex() -> t.MeshObject:
|
|
11
|
+
mesh = bpy.data.meshes.new(mesh_single_vertex.__name__)
|
|
12
|
+
mesh.vertices.add(1)
|
|
13
|
+
mesh.vertices[0].co = (0, 0, 0)
|
|
14
|
+
obj = bpy.data.objects.new(mesh_single_vertex.__name__, mesh)
|
|
15
|
+
bpy.context.scene.collection.objects.link(obj)
|
|
16
|
+
return t.MeshObject(obj)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
def point_cloud(
|
|
21
|
+
points: list[Vector],
|
|
22
|
+
edges: list[tuple[int, int]] | None = None,
|
|
23
|
+
) -> t.MeshObject:
|
|
24
|
+
mesh = bpy.data.meshes.new(point_cloud.__name__)
|
|
25
|
+
mesh.from_pydata(points, edges, [])
|
|
26
|
+
obj = bpy.data.objects.new(point_cloud.__name__, mesh)
|
|
27
|
+
bpy.context.scene.collection.objects.link(obj)
|
|
28
|
+
return t.MeshObject(obj)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def mesh_from_numpy(
|
|
33
|
+
vertices: np.ndarray | None = None,
|
|
34
|
+
edges: np.ndarray | None = None,
|
|
35
|
+
faces: np.ndarray | None = None,
|
|
36
|
+
) -> t.MeshObject:
|
|
37
|
+
if vertices is None:
|
|
38
|
+
vertices = np.array([])
|
|
39
|
+
if edges is None:
|
|
40
|
+
edges = np.array([])
|
|
41
|
+
if faces is None:
|
|
42
|
+
faces = np.array([])
|
|
43
|
+
|
|
44
|
+
mesh = bpy.data.meshes.new(mesh_from_numpy.__name__)
|
|
45
|
+
mesh.from_pydata(vertices, edges, faces)
|
|
46
|
+
obj = bpy.data.objects.new(mesh_from_numpy.__name__, mesh)
|
|
47
|
+
bpy.context.scene.collection.objects.link(obj)
|
|
48
|
+
return t.MeshObject(obj)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def mesh_line(
|
|
52
|
+
points: list[Vector] | np.ndarray,
|
|
53
|
+
) -> t.MeshObject:
|
|
54
|
+
idxs = np.arange(len(points))
|
|
55
|
+
edges = np.stack([idxs[:-1], idxs[1:]], axis=-1)
|
|
56
|
+
|
|
57
|
+
mesh = bpy.data.meshes.new(mesh_line.__name__)
|
|
58
|
+
mesh.from_pydata(points, edges, [])
|
|
59
|
+
obj = bpy.data.objects.new(mesh_line.__name__, mesh)
|
|
60
|
+
bpy.context.scene.collection.objects.link(obj)
|
|
61
|
+
return t.MeshObject(obj)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def empty(
|
|
65
|
+
disp_type: str = "PLAIN_AXES",
|
|
66
|
+
display_size: float = 0.1,
|
|
67
|
+
) -> t.MeshObject:
|
|
68
|
+
obj = bpy.data.objects.new(empty.__name__, None)
|
|
69
|
+
bpy.context.scene.collection.objects.link(obj)
|
|
70
|
+
obj.empty_display_size = display_size
|
|
71
|
+
obj.empty_display_type = disp_type
|
|
72
|
+
return t.MeshObject(obj)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def mesh_uv_sphere(
|
|
76
|
+
segments: int = 32,
|
|
77
|
+
ring_count: int = 16,
|
|
78
|
+
radius: float = 1.0,
|
|
79
|
+
calc_uvs: bool = True,
|
|
80
|
+
enter_editmode: bool = False,
|
|
81
|
+
align: str = "WORLD",
|
|
82
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
83
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
84
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
85
|
+
**kwargs: Any,
|
|
86
|
+
) -> t.MeshObject:
|
|
87
|
+
"""Generate a UV sphere primitive with specified parameters."""
|
|
88
|
+
bpy.ops.mesh.primitive_uv_sphere_add(
|
|
89
|
+
segments=segments,
|
|
90
|
+
ring_count=ring_count,
|
|
91
|
+
radius=radius,
|
|
92
|
+
calc_uvs=calc_uvs,
|
|
93
|
+
enter_editmode=enter_editmode,
|
|
94
|
+
align=align,
|
|
95
|
+
location=location,
|
|
96
|
+
rotation=rotation,
|
|
97
|
+
scale=scale,
|
|
98
|
+
**kwargs,
|
|
99
|
+
)
|
|
100
|
+
obj = bpy.context.active_object
|
|
101
|
+
return t.MeshObject(obj)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def mesh_plane(
|
|
105
|
+
size: float = 2.0,
|
|
106
|
+
calc_uvs: bool = True,
|
|
107
|
+
enter_editmode: bool = False,
|
|
108
|
+
align: str = "WORLD",
|
|
109
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
110
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
111
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
112
|
+
**kwargs: Any,
|
|
113
|
+
) -> t.MeshObject:
|
|
114
|
+
"""Generate a plane primitive with specified parameters."""
|
|
115
|
+
bpy.ops.mesh.primitive_plane_add(
|
|
116
|
+
size=size,
|
|
117
|
+
calc_uvs=calc_uvs,
|
|
118
|
+
enter_editmode=enter_editmode,
|
|
119
|
+
align=align,
|
|
120
|
+
location=location,
|
|
121
|
+
rotation=rotation,
|
|
122
|
+
scale=scale,
|
|
123
|
+
**kwargs,
|
|
124
|
+
)
|
|
125
|
+
obj = bpy.context.active_object
|
|
126
|
+
return t.MeshObject(obj)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def mesh_cube(
|
|
130
|
+
size: float = 2.0,
|
|
131
|
+
calc_uvs: bool = True,
|
|
132
|
+
enter_editmode: bool = False,
|
|
133
|
+
align: str = "WORLD",
|
|
134
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
135
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
136
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
137
|
+
**kwargs: Any,
|
|
138
|
+
) -> t.MeshObject:
|
|
139
|
+
"""Generate a cube primitive with specified parameters."""
|
|
140
|
+
bpy.ops.mesh.primitive_cube_add(
|
|
141
|
+
size=size,
|
|
142
|
+
calc_uvs=calc_uvs,
|
|
143
|
+
enter_editmode=enter_editmode,
|
|
144
|
+
align=align,
|
|
145
|
+
location=Vector(location),
|
|
146
|
+
rotation=Euler(rotation),
|
|
147
|
+
scale=Vector(scale),
|
|
148
|
+
**kwargs,
|
|
149
|
+
)
|
|
150
|
+
obj = bpy.context.active_object
|
|
151
|
+
return t.MeshObject(obj)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def mesh_icosphere(
|
|
155
|
+
subdivisions: int = 2,
|
|
156
|
+
radius: float = 1.0,
|
|
157
|
+
calc_uvs: bool = True,
|
|
158
|
+
enter_editmode: bool = False,
|
|
159
|
+
align: str = "WORLD",
|
|
160
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
161
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
162
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
163
|
+
**kwargs: Any,
|
|
164
|
+
) -> t.MeshObject:
|
|
165
|
+
"""Generate an icosphere primitive with specified parameters."""
|
|
166
|
+
bpy.ops.mesh.primitive_ico_sphere_add(
|
|
167
|
+
subdivisions=subdivisions,
|
|
168
|
+
radius=radius,
|
|
169
|
+
calc_uvs=calc_uvs,
|
|
170
|
+
enter_editmode=enter_editmode,
|
|
171
|
+
align=align,
|
|
172
|
+
location=location,
|
|
173
|
+
rotation=rotation,
|
|
174
|
+
scale=scale,
|
|
175
|
+
**kwargs,
|
|
176
|
+
)
|
|
177
|
+
obj = bpy.context.active_object
|
|
178
|
+
return t.MeshObject(obj)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def mesh_cylinder(
|
|
182
|
+
vertices: int = 32,
|
|
183
|
+
radius: float = 1.0,
|
|
184
|
+
depth: float = 2.0,
|
|
185
|
+
end_fill_type: str = "NGON",
|
|
186
|
+
calc_uvs: bool = True,
|
|
187
|
+
enter_editmode: bool = False,
|
|
188
|
+
align: str = "WORLD",
|
|
189
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
190
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
191
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
192
|
+
**kwargs: Any,
|
|
193
|
+
) -> t.MeshObject:
|
|
194
|
+
"""Generate a cylinder primitive with specified parameters."""
|
|
195
|
+
bpy.ops.mesh.primitive_cylinder_add(
|
|
196
|
+
vertices=vertices,
|
|
197
|
+
radius=radius,
|
|
198
|
+
depth=depth,
|
|
199
|
+
end_fill_type=end_fill_type,
|
|
200
|
+
calc_uvs=calc_uvs,
|
|
201
|
+
enter_editmode=enter_editmode,
|
|
202
|
+
align=align,
|
|
203
|
+
location=location,
|
|
204
|
+
rotation=rotation,
|
|
205
|
+
scale=scale,
|
|
206
|
+
**kwargs,
|
|
207
|
+
)
|
|
208
|
+
obj = bpy.context.active_object
|
|
209
|
+
return t.MeshObject(obj)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def mesh_cone(
|
|
213
|
+
vertices: int = 32,
|
|
214
|
+
radius1: float = 1.0,
|
|
215
|
+
radius2: float = 0.0,
|
|
216
|
+
depth: float = 2.0,
|
|
217
|
+
end_fill_type: str = "NGON",
|
|
218
|
+
calc_uvs: bool = True,
|
|
219
|
+
enter_editmode: bool = False,
|
|
220
|
+
align: str = "WORLD",
|
|
221
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
222
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
223
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
224
|
+
**kwargs: Any,
|
|
225
|
+
) -> t.MeshObject:
|
|
226
|
+
"""Generate a cone primitive with specified parameters."""
|
|
227
|
+
bpy.ops.mesh.primitive_cone_add(
|
|
228
|
+
vertices=vertices,
|
|
229
|
+
radius1=radius1,
|
|
230
|
+
radius2=radius2,
|
|
231
|
+
depth=depth,
|
|
232
|
+
end_fill_type=end_fill_type,
|
|
233
|
+
calc_uvs=calc_uvs,
|
|
234
|
+
enter_editmode=enter_editmode,
|
|
235
|
+
align=align,
|
|
236
|
+
location=location,
|
|
237
|
+
rotation=rotation,
|
|
238
|
+
scale=scale,
|
|
239
|
+
**kwargs,
|
|
240
|
+
)
|
|
241
|
+
obj = bpy.context.active_object
|
|
242
|
+
return t.MeshObject(obj)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def mesh_torus(
|
|
246
|
+
align: str = "WORLD",
|
|
247
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
248
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
249
|
+
major_segments: int = 48,
|
|
250
|
+
minor_segments: int = 12,
|
|
251
|
+
mode: str = "MAJOR_MINOR",
|
|
252
|
+
major_radius: float = 1.0,
|
|
253
|
+
minor_radius: float = 0.25,
|
|
254
|
+
abso_major_rad: float = 1.25,
|
|
255
|
+
abso_minor_rad: float = 0.75,
|
|
256
|
+
generate_uvs: bool = True,
|
|
257
|
+
**kwargs: Any,
|
|
258
|
+
) -> t.MeshObject:
|
|
259
|
+
"""Generate a torus primitive with specified parameters."""
|
|
260
|
+
bpy.ops.mesh.primitive_torus_add(
|
|
261
|
+
align=align,
|
|
262
|
+
location=location,
|
|
263
|
+
rotation=rotation,
|
|
264
|
+
major_segments=major_segments,
|
|
265
|
+
minor_segments=minor_segments,
|
|
266
|
+
mode=mode,
|
|
267
|
+
major_radius=major_radius,
|
|
268
|
+
minor_radius=minor_radius,
|
|
269
|
+
abso_major_rad=abso_major_rad,
|
|
270
|
+
abso_minor_rad=abso_minor_rad,
|
|
271
|
+
generate_uvs=generate_uvs,
|
|
272
|
+
**kwargs,
|
|
273
|
+
)
|
|
274
|
+
obj = bpy.context.active_object
|
|
275
|
+
return t.MeshObject(obj)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def mesh_circle(
|
|
279
|
+
vertices: int = 32,
|
|
280
|
+
radius: float = 1.0,
|
|
281
|
+
fill_type: str = "NOTHING",
|
|
282
|
+
calc_uvs: bool = True,
|
|
283
|
+
enter_editmode: bool = False,
|
|
284
|
+
align: str = "WORLD",
|
|
285
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
286
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
287
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
288
|
+
**kwargs: Any,
|
|
289
|
+
) -> t.MeshObject:
|
|
290
|
+
"""Generate a circle primitive with specified parameters."""
|
|
291
|
+
bpy.ops.mesh.primitive_circle_add(
|
|
292
|
+
vertices=vertices,
|
|
293
|
+
radius=radius,
|
|
294
|
+
fill_type=fill_type,
|
|
295
|
+
calc_uvs=calc_uvs,
|
|
296
|
+
enter_editmode=enter_editmode,
|
|
297
|
+
align=align,
|
|
298
|
+
location=location,
|
|
299
|
+
rotation=rotation,
|
|
300
|
+
scale=scale,
|
|
301
|
+
**kwargs,
|
|
302
|
+
)
|
|
303
|
+
obj = bpy.context.active_object
|
|
304
|
+
return t.MeshObject(obj)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def mesh_grid(
|
|
308
|
+
x_subdivisions: int = 10,
|
|
309
|
+
y_subdivisions: int = 10,
|
|
310
|
+
size: float = 2.0,
|
|
311
|
+
calc_uvs: bool = True,
|
|
312
|
+
enter_editmode: bool = False,
|
|
313
|
+
align: str = "WORLD",
|
|
314
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
315
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
316
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
317
|
+
**kwargs: Any,
|
|
318
|
+
) -> t.MeshObject:
|
|
319
|
+
"""Generate a grid primitive with specified parameters."""
|
|
320
|
+
bpy.ops.mesh.primitive_grid_add(
|
|
321
|
+
x_subdivisions=x_subdivisions,
|
|
322
|
+
y_subdivisions=y_subdivisions,
|
|
323
|
+
size=size,
|
|
324
|
+
calc_uvs=calc_uvs,
|
|
325
|
+
enter_editmode=enter_editmode,
|
|
326
|
+
align=align,
|
|
327
|
+
location=location,
|
|
328
|
+
rotation=rotation,
|
|
329
|
+
scale=scale,
|
|
330
|
+
**kwargs,
|
|
331
|
+
)
|
|
332
|
+
obj = bpy.context.active_object
|
|
333
|
+
return t.MeshObject(obj)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def mesh_monkey(
|
|
337
|
+
size: float = 2.0,
|
|
338
|
+
calc_uvs: bool = True,
|
|
339
|
+
enter_editmode: bool = False,
|
|
340
|
+
align: str = "WORLD",
|
|
341
|
+
location: Vector = Vector((0.0, 0.0, 0.0)),
|
|
342
|
+
rotation: Euler = Euler((0.0, 0.0, 0.0)),
|
|
343
|
+
scale: Vector = Vector((1.0, 1.0, 1.0)),
|
|
344
|
+
**kwargs: Any,
|
|
345
|
+
) -> t.MeshObject:
|
|
346
|
+
"""Generate a monkey (Suzanne) primitive with specified parameters."""
|
|
347
|
+
bpy.ops.mesh.primitive_monkey_add(
|
|
348
|
+
size=size,
|
|
349
|
+
calc_uvs=calc_uvs,
|
|
350
|
+
enter_editmode=enter_editmode,
|
|
351
|
+
align=align,
|
|
352
|
+
location=location,
|
|
353
|
+
rotation=rotation,
|
|
354
|
+
scale=scale,
|
|
355
|
+
**kwargs,
|
|
356
|
+
)
|
|
357
|
+
obj = bpy.context.active_object
|
|
358
|
+
return t.MeshObject(obj)
|
procfunc/ops/uv.py
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
import bpy
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
import procfunc as pf
|
|
7
|
+
from procfunc import types as t
|
|
8
|
+
from procfunc.ops._util import execute_mesh_op
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _ensure_uv_layer(obj: bpy.types.Object, uv_name: str) -> None:
|
|
12
|
+
"""Ensure a UV layer exists with the given name, removing any existing one first."""
|
|
13
|
+
mesh = obj.data
|
|
14
|
+
if uv_name in mesh.uv_layers:
|
|
15
|
+
mesh.uv_layers.remove(mesh.uv_layers[uv_name])
|
|
16
|
+
new_layer = mesh.uv_layers.new(name=uv_name)
|
|
17
|
+
mesh.uv_layers.active = new_layer
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pf.tracer.primitive(mutates=["mutates_obj"])
|
|
21
|
+
def cube_project(
|
|
22
|
+
mutates_obj: t.MeshObject,
|
|
23
|
+
vertex_mask: np.ndarray | None = None,
|
|
24
|
+
edge_mask: np.ndarray | None = None,
|
|
25
|
+
face_mask: np.ndarray | None = None,
|
|
26
|
+
uv_name: str = "UVMap",
|
|
27
|
+
cube_size: float = 1.0,
|
|
28
|
+
correct_aspect: bool = True,
|
|
29
|
+
clip_to_bounds: bool = False,
|
|
30
|
+
scale_to_bounds: bool = False,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Project the UV vertices of the mesh over the six faces of a cube
|
|
34
|
+
|
|
35
|
+
Based on bpy.ops.uv.cube_project
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
vertex_mask: Boolean array selecting vertices to project.
|
|
39
|
+
edge_mask: Boolean array selecting edges to project.
|
|
40
|
+
face_mask: Boolean array selecting faces to project.
|
|
41
|
+
uv_name: Name of the UV layer to create/replace.
|
|
42
|
+
"""
|
|
43
|
+
_ensure_uv_layer(mutates_obj.item(), uv_name)
|
|
44
|
+
execute_mesh_op(
|
|
45
|
+
bpy.ops.uv.cube_project,
|
|
46
|
+
mutates_obj,
|
|
47
|
+
vertex_mask=vertex_mask,
|
|
48
|
+
edge_mask=edge_mask,
|
|
49
|
+
face_mask=face_mask,
|
|
50
|
+
cube_size=cube_size,
|
|
51
|
+
correct_aspect=correct_aspect,
|
|
52
|
+
clip_to_bounds=clip_to_bounds,
|
|
53
|
+
scale_to_bounds=scale_to_bounds,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pf.tracer.primitive(mutates=["mutates_obj"])
|
|
58
|
+
def cylinder_project(
|
|
59
|
+
mutates_obj: t.MeshObject,
|
|
60
|
+
vertex_mask: np.ndarray | None = None,
|
|
61
|
+
edge_mask: np.ndarray | None = None,
|
|
62
|
+
face_mask: np.ndarray | None = None,
|
|
63
|
+
uv_name: str = "UVMap",
|
|
64
|
+
direction: Literal[
|
|
65
|
+
"VIEW_ON_EQUATOR", "VIEW_ON_POLES", "ALIGN_TO_OBJECT"
|
|
66
|
+
] = "VIEW_ON_EQUATOR",
|
|
67
|
+
align: Literal["POLAR_ZX", "POLAR_ZY"] = "POLAR_ZX",
|
|
68
|
+
pole: Literal["PINCH", "FAN"] = "PINCH",
|
|
69
|
+
seam: bool = False,
|
|
70
|
+
radius: float = 1.0,
|
|
71
|
+
correct_aspect: bool = True,
|
|
72
|
+
clip_to_bounds: bool = False,
|
|
73
|
+
scale_to_bounds: bool = False,
|
|
74
|
+
) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Project the UV vertices of the mesh over the curved wall of a cylinder
|
|
77
|
+
|
|
78
|
+
Based on bpy.ops.uv.cylinder_project
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
vertex_mask: Boolean array selecting vertices to project.
|
|
82
|
+
edge_mask: Boolean array selecting edges to project.
|
|
83
|
+
face_mask: Boolean array selecting faces to project.
|
|
84
|
+
uv_name: Name of the UV layer to create/replace.
|
|
85
|
+
"""
|
|
86
|
+
_ensure_uv_layer(mutates_obj.item(), uv_name)
|
|
87
|
+
execute_mesh_op(
|
|
88
|
+
bpy.ops.uv.cylinder_project,
|
|
89
|
+
mutates_obj,
|
|
90
|
+
vertex_mask=vertex_mask,
|
|
91
|
+
edge_mask=edge_mask,
|
|
92
|
+
face_mask=face_mask,
|
|
93
|
+
direction=direction,
|
|
94
|
+
align=align,
|
|
95
|
+
pole=pole,
|
|
96
|
+
seam=seam,
|
|
97
|
+
radius=radius,
|
|
98
|
+
correct_aspect=correct_aspect,
|
|
99
|
+
clip_to_bounds=clip_to_bounds,
|
|
100
|
+
scale_to_bounds=scale_to_bounds,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@pf.tracer.primitive(mutates=["mutates_obj"])
|
|
105
|
+
def project_from_view(
|
|
106
|
+
mutates_obj: t.MeshObject,
|
|
107
|
+
vertex_mask: np.ndarray | None = None,
|
|
108
|
+
edge_mask: np.ndarray | None = None,
|
|
109
|
+
face_mask: np.ndarray | None = None,
|
|
110
|
+
uv_name: str = "UVMap",
|
|
111
|
+
orthographic: bool = False,
|
|
112
|
+
camera_bounds: bool = True,
|
|
113
|
+
correct_aspect: bool = True,
|
|
114
|
+
clip_to_bounds: bool = False,
|
|
115
|
+
scale_to_bounds: bool = False,
|
|
116
|
+
) -> None:
|
|
117
|
+
"""
|
|
118
|
+
Project the UV vertices of the mesh as seen in current 3D view
|
|
119
|
+
|
|
120
|
+
Based on bpy.ops.uv.project_from_view
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
vertex_mask: Boolean array selecting vertices to project.
|
|
124
|
+
edge_mask: Boolean array selecting edges to project.
|
|
125
|
+
face_mask: Boolean array selecting faces to project.
|
|
126
|
+
uv_name: Name of the UV layer to create/replace.
|
|
127
|
+
"""
|
|
128
|
+
_ensure_uv_layer(mutates_obj.item(), uv_name)
|
|
129
|
+
execute_mesh_op(
|
|
130
|
+
bpy.ops.uv.project_from_view,
|
|
131
|
+
mutates_obj,
|
|
132
|
+
vertex_mask=vertex_mask,
|
|
133
|
+
edge_mask=edge_mask,
|
|
134
|
+
face_mask=face_mask,
|
|
135
|
+
orthographic=orthographic,
|
|
136
|
+
camera_bounds=camera_bounds,
|
|
137
|
+
correct_aspect=correct_aspect,
|
|
138
|
+
clip_to_bounds=clip_to_bounds,
|
|
139
|
+
scale_to_bounds=scale_to_bounds,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@pf.tracer.primitive(mutates=["mutates_obj"])
|
|
144
|
+
def smart_project(
|
|
145
|
+
mutates_obj: t.MeshObject,
|
|
146
|
+
vertex_mask: np.ndarray | None = None,
|
|
147
|
+
edge_mask: np.ndarray | None = None,
|
|
148
|
+
face_mask: np.ndarray | None = None,
|
|
149
|
+
uv_name: str = "UVMap",
|
|
150
|
+
angle_limit: float = 1.15192,
|
|
151
|
+
margin_method: Literal["SCALED", "ADD", "FRACTION"] = "SCALED",
|
|
152
|
+
rotate_method: Literal[
|
|
153
|
+
"AXIS_ALIGNED", "AXIS_ALIGNED_X", "AXIS_ALIGNED_Y"
|
|
154
|
+
] = "AXIS_ALIGNED_Y",
|
|
155
|
+
island_margin: float = 0.0,
|
|
156
|
+
area_weight: float = 0.0,
|
|
157
|
+
correct_aspect: bool = True,
|
|
158
|
+
scale_to_bounds: bool = False,
|
|
159
|
+
) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Projection unwraps the selected faces of mesh objects
|
|
162
|
+
|
|
163
|
+
Based on bpy.ops.uv.smart_project
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
vertex_mask: Boolean array selecting vertices to project.
|
|
167
|
+
edge_mask: Boolean array selecting edges to project.
|
|
168
|
+
face_mask: Boolean array selecting faces to project.
|
|
169
|
+
uv_name: Name of the UV layer to create/replace.
|
|
170
|
+
"""
|
|
171
|
+
_ensure_uv_layer(mutates_obj.item(), uv_name)
|
|
172
|
+
execute_mesh_op(
|
|
173
|
+
bpy.ops.uv.smart_project,
|
|
174
|
+
mutates_obj,
|
|
175
|
+
vertex_mask=vertex_mask,
|
|
176
|
+
edge_mask=edge_mask,
|
|
177
|
+
face_mask=face_mask,
|
|
178
|
+
angle_limit=angle_limit,
|
|
179
|
+
margin_method=margin_method,
|
|
180
|
+
rotate_method=rotate_method,
|
|
181
|
+
island_margin=island_margin,
|
|
182
|
+
area_weight=area_weight,
|
|
183
|
+
correct_aspect=correct_aspect,
|
|
184
|
+
scale_to_bounds=scale_to_bounds,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@pf.tracer.primitive(mutates=["mutates_obj"])
|
|
189
|
+
def sphere_project(
|
|
190
|
+
mutates_obj: t.MeshObject,
|
|
191
|
+
vertex_mask: np.ndarray | None = None,
|
|
192
|
+
edge_mask: np.ndarray | None = None,
|
|
193
|
+
face_mask: np.ndarray | None = None,
|
|
194
|
+
uv_name: str = "UVMap",
|
|
195
|
+
direction: Literal[
|
|
196
|
+
"VIEW_ON_EQUATOR", "VIEW_ON_POLES", "ALIGN_TO_OBJECT"
|
|
197
|
+
] = "VIEW_ON_EQUATOR",
|
|
198
|
+
align: Literal["POLAR_ZX", "POLAR_ZY"] = "POLAR_ZX",
|
|
199
|
+
pole: Literal["PINCH", "FAN"] = "PINCH",
|
|
200
|
+
seam: bool = False,
|
|
201
|
+
correct_aspect: bool = True,
|
|
202
|
+
clip_to_bounds: bool = False,
|
|
203
|
+
scale_to_bounds: bool = False,
|
|
204
|
+
) -> None:
|
|
205
|
+
"""
|
|
206
|
+
Project the UV vertices of the mesh over the curved surface of a sphere
|
|
207
|
+
|
|
208
|
+
Based on bpy.ops.uv.sphere_project
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
vertex_mask: Boolean array selecting vertices to project.
|
|
212
|
+
edge_mask: Boolean array selecting edges to project.
|
|
213
|
+
face_mask: Boolean array selecting faces to project.
|
|
214
|
+
uv_name: Name of the UV layer to create/replace.
|
|
215
|
+
"""
|
|
216
|
+
_ensure_uv_layer(mutates_obj.item(), uv_name)
|
|
217
|
+
execute_mesh_op(
|
|
218
|
+
bpy.ops.uv.sphere_project,
|
|
219
|
+
mutates_obj,
|
|
220
|
+
vertex_mask=vertex_mask,
|
|
221
|
+
edge_mask=edge_mask,
|
|
222
|
+
face_mask=face_mask,
|
|
223
|
+
direction=direction,
|
|
224
|
+
align=align,
|
|
225
|
+
pole=pole,
|
|
226
|
+
seam=seam,
|
|
227
|
+
correct_aspect=correct_aspect,
|
|
228
|
+
clip_to_bounds=clip_to_bounds,
|
|
229
|
+
scale_to_bounds=scale_to_bounds,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@pf.tracer.primitive(mutates=["mutates_obj"])
|
|
234
|
+
def unwrap(
|
|
235
|
+
mutates_obj: t.MeshObject,
|
|
236
|
+
vertex_mask: np.ndarray | None = None,
|
|
237
|
+
edge_mask: np.ndarray | None = None,
|
|
238
|
+
face_mask: np.ndarray | None = None,
|
|
239
|
+
uv_name: str = "UVMap",
|
|
240
|
+
method: Literal["ANGLE_BASED", "CONFORMAL"] = "ANGLE_BASED",
|
|
241
|
+
fill_holes: bool = True,
|
|
242
|
+
correct_aspect: bool = True,
|
|
243
|
+
use_subsurf_data: bool = False,
|
|
244
|
+
margin_method: Literal["SCALED", "ADD", "FRACTION"] = "SCALED",
|
|
245
|
+
margin: float = 0.001,
|
|
246
|
+
) -> None:
|
|
247
|
+
"""
|
|
248
|
+
Unwrap the mesh of the object being edited
|
|
249
|
+
|
|
250
|
+
Based on bpy.ops.uv.unwrap
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
vertex_mask: Boolean array selecting vertices to unwrap.
|
|
254
|
+
edge_mask: Boolean array selecting edges to unwrap.
|
|
255
|
+
face_mask: Boolean array selecting faces to unwrap.
|
|
256
|
+
uv_name: Name of the UV layer to create/replace.
|
|
257
|
+
"""
|
|
258
|
+
_ensure_uv_layer(mutates_obj.item(), uv_name)
|
|
259
|
+
execute_mesh_op(
|
|
260
|
+
bpy.ops.uv.unwrap,
|
|
261
|
+
mutates_obj,
|
|
262
|
+
vertex_mask=vertex_mask,
|
|
263
|
+
edge_mask=edge_mask,
|
|
264
|
+
face_mask=face_mask,
|
|
265
|
+
method=method,
|
|
266
|
+
fill_holes=fill_holes,
|
|
267
|
+
correct_aspect=correct_aspect,
|
|
268
|
+
use_subsurf_data=use_subsurf_data,
|
|
269
|
+
margin_method=margin_method,
|
|
270
|
+
margin=margin,
|
|
271
|
+
)
|