Skip to content

Commit

Permalink
update from MN
Browse files Browse the repository at this point in the history
  • Loading branch information
BradyAJohnston committed Dec 18, 2024
1 parent 9997ecf commit 647ff07
Show file tree
Hide file tree
Showing 8 changed files with 2,048 additions and 170 deletions.
24 changes: 22 additions & 2 deletions databpy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
from .object import ObjectTracker, BlenderObject, create_object, create_bob
from .collection import create_collection
from .object import (
ObjectTracker,
BlenderObject,
create_object,
create_bob,
LinkedObjectError,
bdo,
)
from .vdb import import_vdb
import bpy
from .utils import centre, lerp
from .attribute import (
named_attribute,
Expand All @@ -12,3 +19,16 @@
Domains,
DomainType,
)


def register():
bpy.types.Object.uuid = bpy.props.StringProperty(
name="UUID",
description="Unique identifier for the object",
default="",
options={"HIDDEN"},
)


def unregister():
del bpy.types.Object.uuid
93 changes: 25 additions & 68 deletions databpy/attribute.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from dataclasses import dataclass
from enum import Enum
from typing import Type, Union
from typing import Type
import bpy
import numpy as np
from numpy import typing as npt

from pathlib import Path

Expand Down Expand Up @@ -171,6 +170,21 @@ def dtype(self) -> Type:
def n_values(self) -> int:
return np.prod(self.shape, dtype=int)

@classmethod
def from_object(
cls,
obj: bpy.types.Object,
name: str,
atype: AttributeType,
domain: DomainType,
):
att = obj.data.get(name)
if att is None:
att = obj.data.attributes.new(
name=name, type=atype.value.type_name, domain=domain.value.name
)
return Attribute(att)

def from_array(self, array: np.ndarray) -> None:
"""
Set the attribute data from a numpy array
Expand All @@ -182,7 +196,7 @@ def from_array(self, array: np.ndarray) -> None:

self.attribute.data.foreach_set(self.value_name, array.reshape(-1))

def as_array(self) -> Union[npt.ArrayLike, bool, int, float]:
def as_array(self) -> np.ndarray:
"""
Returns the attribute data as a numpy array
"""
Expand Down Expand Up @@ -237,23 +251,6 @@ def store_named_attribute(
-------
bpy.types.Attribute
The added attribute.
Examples
--------
```{python}
import bpy
import numpy as np
from databpy import store_named_attribute, named_attribute
obj = bpy.data.objects['Cube']
data = np.random.rand(len(obj.data.vertices), 3)
print(named_attribute(obj, 'position')) # get the vertex positions as as numpy array
store_named_attribute(obj, data, 'position') # set the vertex positions with random data
named_attribute(obj, 'position') # get the updated vertex positions
```
"""

if isinstance(atype, str):
Expand Down Expand Up @@ -297,48 +294,25 @@ def store_named_attribute(
return attribute


def evaluate_object(obj: bpy.types.Object) -> bpy.types.Object:
def evaluate_object(obj: bpy.types.Object):
"Return an object which has the modifiers evaluated."
obj.update_tag()
eval_obj: bpy.types.Object = obj.evaluated_get( # type: ignore
bpy.context.evaluated_depsgraph_get() # type: ignore
)
return eval_obj
return obj.evaluated_get(bpy.context.evaluated_depsgraph_get())


def named_attribute(
obj: bpy.types.Object, name="position", evaluate=False
) -> npt.ArrayLike:
) -> np.ndarray:
"""
Get the named attribute data from the object, optionally evaluating modifiers first.
Parameters
----------
obj : bpy.types.Object
The Blender object.
name : str, optional
The name of the attribute. Defaults to 'position'.
evaluate : bool, optional
Whether to evaluate the object's modifiers before getting the attribute. Defaults to False.
Parameters:
object (bpy.types.Object): The Blender object.
name (str, optional): The name of the attribute. Defaults to 'position'.
Returns
-------
np.ndarray or bool or int or float
The attribute data as a numpy array, or a single value if the attribute is 1D.
Examples
--------
All data inside of Blender is stored as arbitrary attributes on a mesh, on a certain domain.
We will mostly only interact with the 'POINT' domain, which is the vertices of the mesh.
```{python}
import bpy
from databpy import named_attribute
obj = bpy.data.objects['Cube']
named_attribute(obj, 'position') # get the vertex positions as as numpy array
```
Returns:
np.ndarray: The attribute data as a numpy array.
"""

if evaluate:
obj = evaluate_object(obj)
verbose = False
Expand All @@ -357,23 +331,6 @@ def named_attribute(
def remove_named_attribute(
obj: bpy.types.Object, name: str, domain: str | DomainType = Domains.POINT
):
"""
Remove a named attribute from a Blender object.
Parameters
----------
obj : bpy.types.Object
The Blender object from which the attribute will be removed.
name : str
The name of the attribute to remove.
domain : str or DomainType, optional
The domain of the attribute, by default Domains.POINT.
Raises
------
AttributeError
If the attribute with the specified name does not exist on the mesh.
"""
try:
attr = obj.data.attributes[name]
obj.data.attributes.remove(attr)
Expand Down
Loading

0 comments on commit 647ff07

Please sign in to comment.