Skip to content

Commit

Permalink
Merge pull request #4596 from nortikin/named_attribute
Browse files Browse the repository at this point in the history
Named Attribute node
  • Loading branch information
Durman authored Jul 29, 2022
2 parents e582fab + 51a78d5 commit a1a93ed
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
34 changes: 34 additions & 0 deletions docs/nodes/object_nodes/named_attribute.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Named attribute
===============

Functionality
-------------

The node takes a blender object and an attribute name and tries to find
attribute with such name if it fails it rises an error. The size and type
of attributes remains unchanged by the node.

Category
--------

BPY Data -> Set mesh attribute

Inputs
------

- **Object** - Blender data blocks
- **Name** - name of attribute to read

Outputs
-------

- **Object** - Blender data blocks
- **Attribute** - Values of the attriubte

Usage
-----

Setting and reading some attribute on a mesh

.. image:: https://user-images.githubusercontent.com/28003269/181222478-42302284-b72f-460d-9df2-6fed2b49f625.png
:width: 800px
1 change: 1 addition & 0 deletions docs/nodes/object_nodes/object_nodes_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ Objects
set_mesh_attribute
set_collection
copy_modifiers
named_attribute
1 change: 1 addition & 0 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@
SvSortObjsNode
SvFilterObjsNode
SvSetMeshAttributeNode
SvNamedMeshAttributeNode
SvPointOnMeshNodeMK2
SvOBJRayCastNodeMK2
SvSCNRayCastNodeMK2
Expand Down
84 changes: 84 additions & 0 deletions nodes/object_nodes/named_attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# This file is part of project Sverchok. It's copyrighted by the contributors
# recorded in the version control history of the file, available from
# its original location https://github.com/nortikin/sverchok/commit/master
#
# SPDX-License-Identifier: GPL3
# License-Filename: LICENSE

import numpy as np

import bpy
from sverchok.data_structure import fixed_iter
from sverchok.node_tree import SverchCustomTreeNode


def read_mesh_attribute(obj, name):
attr = obj.data.attributes[name]

if attr.data_type == 'FLOAT':
out = np.zeros(len(attr.data), dtype=np.float32)
attr.data.foreach_get('value', out)
elif attr.data_type == 'INT':
out = np.zeros(len(attr.data), dtype=int)
attr.data.foreach_get('value', out)
elif attr.data_type == 'BOOLEAN':
out = np.zeros(len(attr.data), dtype=bool)
attr.data.foreach_get('value', out)
elif attr.data_type == 'FLOAT_VECTOR':
out = np.zeros(len(attr.data) * 3, dtype=np.float32)
attr.data.foreach_get('vector', out)
out.shape = (-1, 3)
elif attr.data_type == 'FLOAT2':
out = np.zeros(len(attr.data) * 2, dtype=np.float32)
attr.data.foreach_get('vector', out)
out.shape = (-1, 2)
elif attr.data_type == 'FLOAT_COLOR':
out = np.zeros(len(attr.data) * 4, dtype=np.float32)
attr.data.foreach_get('color', out)
out.shape = (-1, 4)
elif attr.data_type == 'BYTE_COLOR':
# it seems blender keeps the values as floats internally
out = np.zeros(len(attr.data) * 4)
attr.data.foreach_get('color', out)
out *= 255
out = out.astype(np.uint8)
out.shape = (-1, 4)
else:
raise TypeError(f"Unknown {attr.data_type=}")
return out


class SvNamedMeshAttributeNode(SverchCustomTreeNode, bpy.types.Node):
"""
Triggers: object mesh
Tooltip: Reading mesh attribute
"""
bl_idname = 'SvNamedMeshAttributeNode'
bl_label = 'Named Attribute'
bl_icon = 'SORTALPHA'

def sv_init(self, context):
self.inputs.new('SvObjectSocket', 'Object')
self.inputs.new('SvTextSocket', 'Name').use_prop = True
self.outputs.new('SvObjectSocket', "Object")
self.outputs.new('SvStringsSocket', "Attribute")

def process(self):
objs = self.inputs['Object'].sv_get(deepcopy=False, default=[])
names = self.inputs['Name'].sv_get(deepcopy=False)

attrs = []
names = fixed_iter(names, len(objs))
for obj, name in zip(objs, names):
name = name[0]
if name:
attrs.append(read_mesh_attribute(obj, name))
else:
attrs.append([])

self.outputs['Object'].sv_set(objs)
self.outputs['Attribute'].sv_set(attrs)


register, unregister = bpy.utils.register_classes_factory(
[SvNamedMeshAttributeNode])

0 comments on commit a1a93ed

Please sign in to comment.