-
Notifications
You must be signed in to change notification settings - Fork 235
/
Copy pathpolygons_centers_mk3.py
129 lines (108 loc) · 4.69 KB
/
polygons_centers_mk3.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
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
import bpy
from mathutils import Vector, Matrix, geometry
from bpy.props import BoolProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import Vector_generate, Vector_degenerate, updateNode
class CentersPolsNodeMK3(SverchCustomTreeNode, bpy.types.Node):
''' Centers of polygons of mesh (not including matrixes, so apply scale-rot-loc ctrl+A) '''
bl_idname = 'CentersPolsNodeMK3'
bl_label = 'Centers polygons'
bl_icon = 'OUTLINER_OB_EMPTY'
sv_icon = 'SV_CENTER_POLYGONS'
Separate: BoolProperty(
name="Separate", description="separate by objects",
default=True, update=updateNode)
def draw_buttons(self, context, layout):
layout.prop(self, "Separate", text="Separate")
def sv_init(self, context):
self.inputs.new('SvVerticesSocket', "Vertices")
self.inputs.new('SvStringsSocket', "Polygons")
self.outputs.new('SvVerticesSocket', "Normals")
self.outputs.new('SvVerticesSocket', "Norm_abs")
self.outputs.new('SvVerticesSocket', "Origins")
self.outputs.new('SvMatrixSocket', "Centers")
def process(self):
verts_socket, poly_socket = self.inputs
norm_socket, norm_abs_socket, origins_socket, centers_socket = self.outputs
if not any([s.is_linked for s in self.outputs]):
return
if not (verts_socket.is_linked and poly_socket.is_linked):
return
pols_ = poly_socket.sv_get()
vers_tupls = verts_socket.sv_get()
vers_vects = Vector_generate(vers_tupls)
# make mesh temp утилитарно - удалить в конце
mat_collect = []
normals_out = []
origins = []
norm_abs_out = []
for verst, versv, pols in zip(vers_tupls, vers_vects, pols_):
normals = []
centrs = []
norm_abs = []
p0_xdirs = []
for p in pols:
v0 = versv[p[0]]
v1 = versv[p[1]]
v2 = versv[p[2]]
# save direction of 1st point in polygon
p0_xdirs.append(v0)
# normals
norm = geometry.normal(v0, v1, v2)
normals.append(norm)
# centrs
x,y,z = zip(*[verst[poi] for poi in p])
x,y,z = sum(x)/len(x), sum(y)/len(y), sum(z)/len(z)
current_center = Vector((x,y,z))
centrs.append(current_center)
# normal absolute !!!
# это совершенно нормально!!! ;-)
norm_abs.append(current_center+norm)
if self.Separate:
norm_abs_out.append(norm_abs)
origins.append(centrs)
normals_out.append(normals)
else:
norm_abs_out.extend(norm_abs)
origins.extend(centrs)
normals_out.extend(normals)
mat_collect_ = []
for cen, nor, p0 in zip(centrs, normals, p0_xdirs):
zdir = nor
xdir = (Vector(p0) - cen).normalized()
ydir = zdir.cross(xdir)
lM = [(xdir[0], ydir[0], zdir[0], cen[0]),
(xdir[1], ydir[1], zdir[1], cen[1]),
(xdir[2], ydir[2], zdir[2], cen[2]),
(0.0, 0.0, 0.0, 1.0)]
mat_collect_.append(Matrix(lM))
mat_collect.extend(mat_collect_)
if not self.Separate:
norm_abs_out = [norm_abs_out]
origins = [origins]
normals_out = [normals_out]
centers_socket.sv_set(mat_collect)
norm_abs_socket.sv_set(Vector_degenerate(norm_abs_out))
origins_socket.sv_set(Vector_degenerate(origins))
norm_socket.sv_set(Vector_degenerate(normals_out))
def register():
bpy.utils.register_class(CentersPolsNodeMK3)
def unregister():
bpy.utils.unregister_class(CentersPolsNodeMK3)