Skip to content

Commit dddf0d9

Browse files
committed
Add Attribute class for named attributes
1 parent a3337db commit dddf0d9

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed

api/static/attribute.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class Attribute:
2+
"""
3+
A class that represents named attributes, providing methods for accessing and storing them.
4+
5+
Create an attribute with a name, data type, and optional domain.
6+
```python
7+
height_level = Attribute(
8+
"height_level",
9+
NamedAttribute.DataType.FLOAT,
10+
StoreNamedAttribute.Domain.POINT # optional
11+
)
12+
```
13+
14+
Access the attribute value by calling the class instance.
15+
```python
16+
height_level()
17+
```
18+
19+
Store a value for the named attribute on some geometry with `store(...)`.
20+
```python
21+
height_level.store(geometry, value)
22+
```
23+
24+
Check if the attribute exists on some geometry with `exists()`.
25+
```python
26+
selection = height_level.exists()
27+
```
28+
"""
29+
name: str
30+
data_type: 'NamedAttribute.DataType'
31+
domain: 'StoreNamedAttribute.Domain'
32+
33+
def __init__(
34+
self,
35+
name: str,
36+
data_type: 'NamedAttribute.DataType',
37+
domain: 'StoreNamedAttribute.Domain' = 'POINT'
38+
):
39+
self.name = name
40+
self.data_type = data_type
41+
self.domain = domain
42+
43+
def __call__(self, *args, **kwargs):
44+
"""
45+
Creates a "Named Attribute" node with the correct arguments passed, and returns the "Attribute" socket.
46+
"""
47+
from geometry_script import named_attribute
48+
return named_attribute(data_type=self.data_type, name=self.name, *args, **kwargs).attribute
49+
50+
def exists(self, *args, **kwargs):
51+
"""
52+
Creates a "Named Attribute" node with the correct arguments passed, and returns the "Exists" socket.
53+
"""
54+
from geometry_script import named_attribute
55+
return named_attribute(data_type=self.data_type, name=self.name, *args, **kwargs).exists
56+
57+
def store(self, geometry: 'Geometry', value, *args, **kwargs) -> 'Geometry':
58+
"""
59+
Creates a "Store Named Attribute" node with the correct arguments passed, and returns the modified `Geometry`.
60+
"""
61+
from geometry_script import store_named_attribute
62+
return store_named_attribute(
63+
data_type=self.data_type,
64+
domain=self.domain,
65+
geometry=geometry,
66+
name=self.name,
67+
value=value,
68+
*args,
69+
**kwargs
70+
)

api/tree.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
from .state import State
88
from .types import *
99
from .node_mapper import *
10-
from .static.input_group import *
10+
from .static.attribute import *
1111
from .static.expression import *
12+
from .static.input_group import *
1213

1314
def _as_iterable(x):
1415
try:

api/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ def map_case_name(i):
99

1010
def socket_type_to_data_type(socket_type):
1111
match socket_type:
12+
case 'VALUE':
13+
return 'FLOAT'
1214
case 'VECTOR':
1315
return 'FLOAT_VECTOR'
1416
case 'COLOR':

book/src/api/advanced-scripting/attributes.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,24 @@ Any additional keyword arguments can be passed as normal.
4545

4646
```python
4747
c.transfer(position(), mapping=TransferAttribute.Mapping.INDEX)
48+
```
49+
50+
## Named Attributes
51+
52+
Custom attributes can be created by name.
53+
The safest way to use named attributes is with the `Attribute` class.
54+
55+
Create a named attribute with a data type and optional domain, then use the `store(...)`, `exists()`, and `__call__(...)` methods to use it.
56+
57+
```python
58+
# Create the attribute
59+
my_custom_attribute = Attribute(
60+
"my_custom_attribute",
61+
NamedAttribute.DataType.FLOAT, # declare the data type once
62+
StoreNamedAttribute.Domain.INSTANCE # optional
63+
)
64+
# Store a value
65+
geometry = my_custom_attribute.store(geometry, 0.5)
66+
# Use the value by calling the attribute
67+
geometry = geometry.set_position(offset=my_custom_attribute())
4868
```

0 commit comments

Comments
 (0)