Не подтверждена Коммит 95050e5e создал по автору Victor Doval's avatar Victor Doval Зафиксировано автором GitHub
Просмотр файлов

Min, Max, Size and 2D for Bounding Box Node (#2575)

* added bbox_mk2

* bboxMk2 compact UI

* bbox mk2 added 2D mode

* bbox mk2 2D mode to docs

* bbox mk2 refactoring

* bbox mk2 more refactoring
владелец b69f0517
......@@ -4,13 +4,20 @@ Bounding Box
Functionality
-------------
Generates a special ordered *bounding box* from incoming Vertices.
Generates a special ordered *bounding box* from incoming Vertices.
Inputs
------
**Vertices**, or a nested list of vertices that represent separate objects.
Parameters
----------
2D / 3D: The 2D implementation works over the XY plane always outputting 0 in the Z coordinate, and instead of a box produces a rectangle.
Min, Max and Size: Chose which outputs you want the node to display.
Outputs
-------
......@@ -21,9 +28,29 @@ Outputs
+----------+-----------+----------------------------------------------------------------------------+
| Edges | Key Lists | One or more sets of Edges corresponding to the Vertices of the same index. |
+----------+-----------+----------------------------------------------------------------------------+
| Mean | Vectors | Arithmetic averages of the incoming sets of vertices |
| Mean | Vectors | Arithmetic averages of the incoming sets of vertices. |
+----------+-----------+----------------------------------------------------------------------------+
| Center | Matrix | Represents the *Center* of the bounding box; the average of its vertices. |
| | | The scale of the matrix would make a box with size of 1 unit to match the |
| | | size the desired bounding box. |
+----------+-----------+----------------------------------------------------------------------------+
| Min X | Scalar | Minimum value on the X axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Min Y | Scalar | Minimum value on the Y axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Min Z | Scalar | Minimum value on the Z axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Center | Matrix | Represents the *Center* of the bounding box; the average of its vertices |
| Max X | Scalar | Maximum value on the X axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Max Y | Scalar | Maximum value on the Y axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Max Z | Scalar | Maximum value on the Z axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Size X | Scalar | Size on the X axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Size Y | Scalar | Size on the Y axis. |
+----------+-----------+----------------------------------------------------------------------------+
| Size Z | Scalar | Size on the Z axis. |
+----------+-----------+----------------------------------------------------------------------------+
......@@ -41,7 +68,12 @@ Examples
.. image:: https://cloud.githubusercontent.com/assets/619340/4186538/def29d62-3761-11e4-8069-b9544e2ad62a.PNG
:alt: BBox_Center3.PNG
*2D Mode: produces rectangles at z = 0*
.. image:: https://user-images.githubusercontent.com/10011941/66115789-d1a9c300-e5d1-11e9-96d7-27b01db9a78d.png
:alt: Bounding_Box_2D_Sverchok_Procedural_Blender.PNG
Notes
-----
GitHub issue tracker `discussion about this node <https://github.com/nortikin/sverchok/issues/161>`_
GitHub issue tracker discussion about this node `here <https://github.com/nortikin/sverchok/issues/161>`_ and `here <https://github.com/nortikin/sverchok/pull/2575>`
......@@ -49,7 +49,7 @@
SvRegularSolid
## Analyzers
SvBBoxNode
SvBBoxNodeMk2
SvDiameterNode
SvVolumeNode
SvAreaNode
......
# ##### 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 #####
from itertools import product
import bpy
from bpy.props import BoolVectorProperty, EnumProperty
from mathutils import Matrix
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import dataCorrect, updateNode
class SvBBoxNodeMk2(bpy.types.Node, SverchCustomTreeNode):
'''Bounding box'''
bl_idname = 'SvBBoxNodeMk2'
bl_label = 'Bounding box'
bl_icon = 'NONE'
sv_icon = 'SV_BOUNDING_BOX'
def update_sockets(self, context):
bools = [self.min_list, self.max_list, self.size_list]
dims = int(self.dimensions[0])
for i in range(3):
for j in range(3):
out_index = 4 + j + 3*i
hidden = self.outputs[out_index].hide_safe
if bools[i][j] and j < dims:
if hidden:
self.outputs[out_index].hide_safe = False
else:
self.outputs[out_index].hide_safe = True
updateNode(self, context)
min_list: BoolVectorProperty(
name='Min', description="Show Minimum values sockets", size=3, update=update_sockets)
max_list: BoolVectorProperty(
name='Max', description="Show Maximun values sockets", size=3, update=update_sockets)
size_list: BoolVectorProperty(
name='Size', description="Show Size values sockets", size=3, update=update_sockets)
implentation_modes = [
("2D", "2D", "Outputs Rectangle over XY plane", 0),
("3D", "3D", "Outputs standard bounding box", 1)]
dimensions: EnumProperty(
name='Implementation', items=implentation_modes,
description='Choose calculation method',
default="3D", update=update_sockets)
def draw_buttons(self, context, layout):
layout .prop(self, 'dimensions', expand=True)
col = layout.column(align=True)
titles = ["Min", "Max", "Size"]
prop = ['min_list', 'max_list', 'size_list']
dims = int(self.dimensions[0])
for i in range(3):
row = col.row(align=True)
row.label(text=titles[i])
row2 = row.row(align=True)
for j in range(dims):
row2 .prop(self, prop[i], index=j, text='XYZ'[j], toggle=True)
def sv_init(self, context):
son = self.outputs.new
self.inputs.new('SvVerticesSocket', 'Vertices')
son('SvVerticesSocket', 'Vertices')
son('SvStringsSocket', 'Edges')
son('SvVerticesSocket', 'Mean')
son('SvMatrixSocket', 'Center')
titles = ['Min', 'Max', 'Size']
for j in range(3):
for i in range(3):
son('SvStringsSocket', titles[j] + ' ' + 'XYZ'[i])
self.update_sockets(context)
def generate_matrix(self, maxmin, dims, to_2d):
center = [(u+v)*.5 for u, v in maxmin[:dims]]
scale = [(u-v) for u, v in maxmin[:dims]]
if to_2d:
center += [0]
scale += [1]
mat = Matrix.Translation(center)
for i, sca in enumerate(scale):
mat[i][i] = sca
return mat
def generate_mean(self, verts, dims, to_2d):
avr = list(map(sum, zip(*verts)))
avr = [n/len(verts) for n in avr[:dims]]
if to_2d:
avr += [0]
return [avr]
def process(self):
if not self.inputs['Vertices'].is_linked:
return
if not any(s.is_linked for s in self.outputs):
return
has_mat_out = bool(self.outputs['Center'].is_linked)
has_mean = bool(self.outputs['Mean'].is_linked)
has_vert_out = bool(self.outputs['Vertices'].is_linked)
verts = self.inputs['Vertices'].sv_get(deepcopy=False)
verts = dataCorrect(verts, nominal_dept=2)
has_limits = any(s.is_linked for s in self.outputs[4:])
if verts:
verts_out = []
edges_out = []
edges = [
(0, 1), (1, 3), (3, 2), (2, 0), # bottom edges
(4, 5), (5, 7), (7, 6), (6, 4), # top edges
(0, 4), (1, 5), (2, 6), (3, 7) # sides
]
mat_out = []
mean_out = []
min_vals = [[], [], []]
max_vals = [[], [], []]
size_vals = [[], [], []]
to_2d = self.dimensions == '2D'
dims = int(self.dimensions[0])
for vec in verts:
if has_mat_out or has_vert_out or has_limits:
maxmin = list(zip(map(max, *vec), map(min, *vec)))
if has_vert_out:
out = list(product(*reversed(maxmin)))
v_out = [l[::-1] for l in out[::-1]]
if to_2d:
verts_out.append([[v[0], v[1], 0] for v in v_out[:4]])
edges = edges[:4]
else:
verts_out.append(v_out)
edges_out.append(edges)
if has_mat_out:
mat_out.append(self.generate_matrix(maxmin, dims, to_2d))
if has_mean:
mean_out.append(self.generate_mean(v, dims, to_2d))
if has_limits:
for i in range(dims):
min_vals[i].append([maxmin[i][1]])
max_vals[i].append([maxmin[i][0]])
size_vals[i].append([maxmin[i][0] - maxmin[i][1]])
if has_vert_out:
self.outputs['Vertices'].sv_set(verts_out)
if self.outputs['Edges'].is_linked:
self.outputs['Edges'].sv_set(edges_out)
if has_mean:
self.outputs['Mean'].sv_set(mean_out)
if self.outputs['Center'].is_linked:
self.outputs['Center'].sv_set(mat_out)
vals = [min_vals, max_vals, size_vals]
for j in range(3):
for i, socket in enumerate(self.outputs[4+3*j:7+3*j]):
if socket.is_linked:
socket.sv_set(vals[j][i])
def register():
bpy.utils.register_class(SvBBoxNodeMk2)
def unregister():
bpy.utils.unregister_class(SvBBoxNodeMk2)
......@@ -32,6 +32,8 @@ class SvBBoxNode(bpy.types.Node, SverchCustomTreeNode):
bl_icon = 'NONE'
sv_icon = 'SV_BOUNDING_BOX'
replacement_nodes = [('SvBBoxNodeMk2', None, None)]
def sv_init(self, context):
self.inputs.new('SvVerticesSocket', 'Vertices')
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать