Открыть боковую панель
nikitronn
sverchok
Коммиты
c4274f83
Не подтверждена
Коммит
c4274f83
создал
Сен 21, 2019
по автору
Ilya V. Portnov
Зафиксировано автором
GitHub
Сен 21, 2019
Просмотр файлов
Merge pull request #2542 from nortikin/b28_calc_mask
Port "calc_mask" node to 2.80 branch
владельцы
a2aeea3d
8173e7f5
Изменения
6
Скрыть пробелы
Построчно
Рядом
data_structure.py
Просмотр файла @
c4274f83
...
...
@@ -367,6 +367,42 @@ def describe_data_shape(data):
nesting
,
result
=
helper
(
data
)
return
"Level {}: {}"
.
format
(
nesting
,
result
)
def
calc_mask
(
subset_data
,
set_data
,
level
=
0
,
negate
=
False
,
ignore_order
=
True
):
"""
Calculate mask: for each item in set_data, return True if it is present in subset_data.
The function can work at any specified level.
subset_data: subset, for example [1]
set_data: set, for example [1, 2, 3]
level: 0 to check immediate members of set and subset; 1 to work with lists of lists and so on.
negate: if True, then result will be negated (True if item of set is not present in subset).
ignore_order: when comparing lists, ignore items order.
Raises an exception if nesting level of input sets is less than specified level parameter.
calc_mask([1], [1,2,3]) == [True, False, False])
calc_mask([1], [1,2,3], negate=True) == [False, True, True]
"""
if
level
==
0
:
if
not
isinstance
(
subset_data
,
(
tuple
,
list
)):
raise
Exception
(
"Specified level is too high for given Subset"
)
if
not
isinstance
(
set_data
,
(
tuple
,
list
)):
raise
Exception
(
"Specified level is too high for given Set"
)
if
ignore_order
and
get_data_nesting_level
(
subset_data
)
>
1
:
if
negate
:
return
[
set
(
item
)
not
in
map
(
set
,
subset_data
)
for
item
in
set_data
]
else
:
return
[
set
(
item
)
in
map
(
set
,
subset_data
)
for
item
in
set_data
]
else
:
if
negate
:
return
[
item
not
in
subset_data
for
item
in
set_data
]
else
:
return
[
item
in
subset_data
for
item
in
set_data
]
else
:
sub_objects
=
match_long_repeat
([
subset_data
,
set_data
])
return
[
calc_mask
(
subset_item
,
set_item
,
level
-
1
,
negate
,
ignore_order
)
for
subset_item
,
set_item
in
zip
(
*
sub_objects
)]
#####################################################
################### matrix magic ####################
#####################################################
...
...
docs/nodes/list_masks/calc_mask.rst
0 → 100644
Просмотр файла @
c4274f83
Calculate Mask
==============
Functionality
-------------
This node calculates masks from two input lists (Set and Subset). For each item
in the Set, it returns True if the item is present in Subset, otherwise it
returns False.
There are nodes, which output, for example, "All faces" and "Processed faces"
or smth like that. To do something with that output, it would be usually more
effective to deal with "All faces" and "Processed faces mask" instead.
The node can work on different levels of data trees. For example, given Subset
= `[[1, 2], [3,4]]` and Set = `[[1, 2], [3, 4], [5, 6]]`:
* with level = 0 it will output `[True, True, False]`
* with level = 1 it will output `[[True, True], [True, True], [False, False]]`
Given Subset = `[[1], [5,6]]` and Set = `[[1, 2, 3], [7, 8, 9]]`:
* with level = 0 it will output `[False, False]` (because, for example, there
is no `[1, 2, 3]` in the `[[1], [5,6]]`)
* with level = 1, it will output `[[True, False, False], [False, False, False]]`
Inputs
------
This node has the following inputs:
* **Subset**. List of "good" data items to be checked against.
* **Set**. The whole set of data items.
Parameters
----------
This node has the following parameters:
* **Negate**. If checked, then the resulting mask will be negated. I.e., the
node will output True if item of Set is *not* present in Subset. Unchecked by
default.
* **Ignore order**. If checked, then, while comparing lists, the node will not
take into account the order of items in these lists. For example, is `[1, 2]`
the same as `[2, 1]`? No, if **Ignore order** is not checked.
Outputs
-------
This node has only one output: **Mask**. Number of items in this outuput is
equal to number of items in the **Set** input.
Example of usage
----------------
This node can, for example, be used to apply **Inset Special** node iteratively:
.. image:: https://user-images.githubusercontent.com/284644/58757902-82715a00-852d-11e9-9288-369607f5229d.png
docs/nodes/list_masks/list_masks_index.rst
Просмотр файла @
c4274f83
...
...
@@ -10,3 +10,5 @@ List Masks
mask_converter
mask_to_index
index_to_mask
calc_mask
index.md
Просмотр файла @
c4274f83
...
...
@@ -138,6 +138,7 @@
SvMaskConvertNode
SvMaskToIndexNode
SvIndexToMaskNode
SvCalcMaskNode
## List Mutators
SvListModifierNode
...
...
@@ -358,4 +359,4 @@
SvContourNode
SvPlanarEdgenetToPolygons
SvPulgaPhysicsNode
SvTopologySimple
\ Нет новой строки в конце файла
SvTopologySimple
nodes/list_masks/calc_mask.py
0 → 100644
Просмотр файла @
c4274f83
# ##### 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
bpy.props
import
BoolProperty
,
EnumProperty
,
IntProperty
from
sverchok.node_tree
import
SverchCustomTreeNode
from
sverchok.data_structure
import
updateNode
,
match_long_repeat
,
fullList
,
calc_mask
class
SvCalcMaskNode
(
bpy
.
types
.
Node
,
SverchCustomTreeNode
):
"""
Triggers: Calculate Mask
Tooltip: Calculate mask from two sets of objects
"""
bl_idname
=
'SvCalcMaskNode'
bl_label
=
'Calculate Mask'
bl_icon
=
'OUTLINER_OB_EMPTY'
level
:
IntProperty
(
name
=
'Level'
,
description
=
"List level to operate on"
,
min
=
0
,
default
=
0
,
update
=
updateNode
)
negate
:
BoolProperty
(
name
=
'Negate'
,
description
=
'Negate mask'
,
update
=
updateNode
)
ignore_order
:
BoolProperty
(
name
=
'Ignore order'
,
description
=
"Ignore items order while comparing lists"
,
default
=
True
,
update
=
updateNode
)
def
draw_buttons
(
self
,
context
,
layout
):
layout
.
prop
(
self
,
'level'
)
layout
.
prop
(
self
,
'negate'
)
layout
.
prop
(
self
,
'ignore_order'
)
def
sv_init
(
self
,
context
):
self
.
inputs
.
new
(
'SvStringsSocket'
,
"Subset"
)
self
.
inputs
.
new
(
'SvStringsSocket'
,
"Set"
)
self
.
outputs
.
new
(
'SvStringsSocket'
,
'Mask'
)
def
process
(
self
):
if
not
any
(
output
.
is_linked
for
output
in
self
.
outputs
):
return
subset_s
=
self
.
inputs
[
'Subset'
].
sv_get
(
default
=
[[]])
set_s
=
self
.
inputs
[
'Set'
].
sv_get
(
default
=
[[]])
out_masks
=
[]
objects
=
match_long_repeat
([
subset_s
,
set_s
])
for
subset
,
set
in
zip
(
*
objects
):
mask
=
calc_mask
(
subset
,
set
,
level
=
self
.
level
,
negate
=
self
.
negate
,
ignore_order
=
self
.
ignore_order
)
out_masks
.
append
(
mask
)
self
.
outputs
[
'Mask'
].
sv_set
(
out_masks
)
def
register
():
bpy
.
utils
.
register_class
(
SvCalcMaskNode
)
def
unregister
():
bpy
.
utils
.
unregister_class
(
SvCalcMaskNode
)
tests/data_structure_tests.py
Просмотр файла @
c4274f83
...
...
@@ -68,3 +68,53 @@ class DataStructureTests(SverchokTestCase):
self
.
subtest_assert_equals
(
describe_data_shape
([
1
]),
'Level 1: list [1] of int'
)
self
.
subtest_assert_equals
(
describe_data_shape
([[(
1
,
2
,
3
)]]),
'Level 3: list [1] of list [1] of tuple [3] of int'
)
class
CalcMaskTests
(
SverchokTestCase
):
def
test_calc_mask_1
(
self
):
subset
=
[
1
]
set
=
[
1
,
2
,
3
]
mask
=
calc_mask
(
subset
,
set
,
level
=
0
)
expected
=
[
True
,
False
,
False
]
self
.
assertEquals
(
mask
,
expected
)
def
test_calc_mask_2
(
self
):
subset
=
[
1
]
set
=
[
1
,
2
,
3
]
mask
=
calc_mask
(
subset
,
set
,
negate
=
True
)
expected
=
[
False
,
True
,
True
]
self
.
assertEquals
(
mask
,
expected
)
def
test_calc_mask_3
(
self
):
subset
=
[[
1
,
2
],
[
3
,
4
]]
set
=
[[
1
,
2
],
[
3
,
4
],
[
5
,
6
]]
mask
=
calc_mask
(
subset
,
set
,
level
=
0
)
expected
=
[
True
,
True
,
False
]
self
.
assertEquals
(
mask
,
expected
)
def
test_calc_mask_4
(
self
):
subset
=
[[
1
,
2
],
[
3
,
4
]]
set
=
[[
1
,
2
],
[
3
,
4
],
[
5
,
6
]]
mask
=
calc_mask
(
subset
,
set
,
level
=
1
)
expected
=
[[
True
,
True
],
[
True
,
True
],
[
False
,
False
]]
self
.
assertEquals
(
mask
,
expected
)
def
test_calc_mask_5
(
self
):
subset
=
[[
1
],
[
5
,
6
]]
set
=
[[
1
,
2
,
3
],
[
7
,
8
,
9
]]
mask
=
calc_mask
(
subset
,
set
,
level
=
0
)
expected
=
[
False
,
False
]
self
.
assertEquals
(
mask
,
expected
)
def
test_calc_mask_6
(
self
):
subset
=
[[
1
],
[
5
,
6
]]
set
=
[[
1
,
2
,
3
],
[
7
,
8
,
9
]]
mask
=
calc_mask
(
subset
,
set
,
level
=
1
)
expected
=
[[
True
,
False
,
False
],
[
False
,
False
,
False
]]
self
.
assertEquals
(
mask
,
expected
)
def
test_calc_mask_7
(
self
):
subset
=
[[
1
,
2
],
[
3
,
4
]]
set
=
[[
2
,
1
],
[
5
,
6
]]
mask
=
calc_mask
(
subset
,
set
,
ignore_order
=
True
)
expected
=
[
True
,
False
]
self
.
assertEquals
(
mask
,
expected
)
Редактирование
Предварительный просмотр
Поддерживает Markdown
0%
Попробовать снова
или
прикрепить новый файл
.
Отмена
You are about to add
0
people
to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Отмена
Пожалуйста,
зарегистрируйтесь
или
войдите
чтобы прокомментировать