-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunscatter.py
132 lines (113 loc) · 5.13 KB
/
unscatter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'''
Copyright (C) 2020-2023 Orange Turbine
https://orangeturbine.com
This file is part of Scattershot, created by Jonathan Lampel.
All code distributed with this add-on is open source as described below.
Scattershot is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>.
'''
import bpy
import pprint
from bpy.types import (Operator)
from bpy.props import (BoolProperty, EnumProperty)
from pprint import pprint
from . import defaults
from .utilities.utilities import get_scatter_sources, get_groups
def extract_images(self, selected_nodes):
nodes = selected_nodes[0].id_data.nodes
scatter_nodes = [x for x in selected_nodes if get_scatter_sources([x])]
for scatter_node in scatter_nodes:
inner_textures = []
new_textures = []
scatter_sources = get_scatter_sources([scatter_node])
for scatter_source in scatter_sources:
for node in scatter_source.node_tree.nodes:
if node.type == 'TEX_IMAGE' and node not in inner_textures: inner_textures.append(node)
columns = 0
for image_idx, image in enumerate(inner_textures):
new_image = nodes.new("ShaderNodeTexImage")
new_textures.append(new_image)
new_image.image = image.image
new_image.image.colorspace_settings.name = image.image.colorspace_settings.name
new_image.location = [scatter_node.location[0] + (250 * columns), scatter_node.location[1] - (285 * (image_idx % 4))]
new_image.projection = self.projection
new_image.interpolation = self.interpolation
new_image.extension = self.extension
if (image_idx + 1) % 4 == 0: columns += 1
return new_textures
def remove_scatter_nodes(selected_nodes):
nodes = selected_nodes[0].id_data.nodes
for node in selected_nodes:
if get_scatter_sources([node]):
nodes.remove(node)
# trees_to_delete = []
# groups = get_groups(selected_nodes)
# trees_to_delete.extend(groups)
# for tree in [x.name for x in trees_to_delete]:
# if tree in [x.name for x in bpy.data.node_groups]:
# bpy.data.node_groups.remove(bpy.data.node_groups[tree])
class NODE_OT_unscatter(Operator):
bl_label = "Un-Scatter"
bl_idname = "node.unscatter"
bl_description = "Reverses Voronoi Scatter"
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
bl_options = {'REGISTER', 'UNDO'}
interpolation: bpy.props.EnumProperty(
name = "Pixel Interpolation",
description ="The pixel interpolation for each image",
items = [
("Linear", "Linear", "Linear interpolation, Blender's default"),
("Closest", "Closest", "No interpolation"),
("Cubic", "Cubic", "Cubic interpolation. Smoothest option"),
("Smart", "Smart", "Cubic when magifying, otherwise linear (OSL use only)")
],
default = defaults.unscatter['interpolation'],
)
projection: bpy.props.EnumProperty(
name="Projection",
description="Method to project texture on an object with a 3d texture vector",
items = [
("FLAT", "Flat", "projected from the X Y coordiantes of the texture vector"),
("BOX", "Box", "Tri-planar projection"),
("SPHERE", "Sphere", "Image is projected spherically with the Z axis as the center"),
("TUBE", "Tube", "Image is projected from a cylinder with the Z axis as the center"),
],
default = defaults.unscatter['projection'],
)
extension: bpy.props.EnumProperty(
name="Extension",
description="How the image is extrapolated beyond its origional bounds",
items=[
("REPEAT", "Repeat", "Repeats texture horizontally and vertically"),
("CLIP", "Clip", "Sets pixels outside of texture as transparent"),
("EXTEND", "Extend", "Repeats only the boundary pixels of the texture")
],
default = defaults.unscatter['extension'],
)
@classmethod
def poll(cls, context):
if context.area.ui_type == 'ShaderNodeTree' and context.selected_nodes:
return get_scatter_sources(context.selected_nodes)
else:
return False
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def execute(self, context):
selected_nodes = context.selected_nodes
extract_images(self, selected_nodes)
remove_scatter_nodes(selected_nodes)
return {'FINISHED'}
def register():
bpy.utils.register_class(NODE_OT_unscatter)
def unregister():
bpy.utils.unregister_class(NODE_OT_unscatter)