Skip to content

Commit

Permalink
tinkering
Browse files Browse the repository at this point in the history
  • Loading branch information
BradyAJohnston committed Oct 31, 2024
1 parent 6ae137f commit 2048c8b
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 23 deletions.
12 changes: 6 additions & 6 deletions molecularnodes/blender/bpyd/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@
from pathlib import Path


def evaluate_object(obj: bpy.types.Object):
"Return an object which has the modifiers evaluated."
obj.update_tag()
return obj.evaluated_get(bpy.context.evaluated_depsgraph_get())


def path_resolve(path: str | Path) -> Path:
if isinstance(path, str):
return Path(bpy.path.abspath(path))
Expand Down Expand Up @@ -297,6 +291,12 @@ def store_named_attribute(
return attribute


def evaluate_object(obj: bpy.types.Object):
"Return an object which has the modifiers evaluated."
obj.update_tag()
return obj.evaluated_get(bpy.context.evaluated_depsgraph_get())


def named_attribute(
obj: bpy.types.Object, name="position", evaluate=False
) -> np.ndarray:
Expand Down
38 changes: 34 additions & 4 deletions molecularnodes/blender/bpyd/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import numpy as np
from typing import Optional
from .attribute import (
evaluate_object,
AttributeTypes,
AttributeType,
Domains,
Expand Down Expand Up @@ -185,12 +184,43 @@ def store_named_attribute(
)
return self

def evaluate(self):
return BlenderObject(evaluate_object(self.object))

def named_attribute(self, name: str, evaluate: bool = False) -> np.ndarray:
"""
Retrieve a named attribute from the object.
Optionally, evaluate the object before reading the named attribute
Parameters
----------
name : str
Name of the attribute to get.
evaluate : bool, optional
Whether to evaluate the object before reading the attribute (default is False).
Returns
-------
np.ndarray
The attribute read from the mesh as a numpy array.
"""
return attribute.named_attribute(self.object, name=name, evaluate=evaluate)

def evaluate(self):
obj = self.object
obj.update_tag()
evluated_obj = obj.evaluated_get(bpy.context.evaluated_depsgraph_get())
return BlenderObject(evluated_obj)

@property
def attributes(self):
return self.object.data.attributes

@property
def vertices(self):
return self.object.data.vertices

@property
def edges(self):
return self.object.data.edges

def transform_origin(self, matrix: Matrix) -> None:
self.object.matrix_local = matrix * self.object.matrix_world

Expand Down
8 changes: 4 additions & 4 deletions molecularnodes/blender/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import numpy as np

from . import coll, nodes
from .bpyd.attribute import AttributeTypes, evaluate_object
from .bpyd.attribute import AttributeTypes
from .bpyd.object import ObjectTracker, create_object, BlenderObject


Expand Down Expand Up @@ -67,13 +67,13 @@ def evaluate_using_mesh(obj):
"""
# create an empty mesh object. It's modifiers can be evaluated but some other
# object types can't be currently through the API
debug_obj = create_object()
mod = nodes.get_mod(debug_obj)
bob = BlenderObject(create_object())
mod = nodes.get_mod(bob.object)
mod.node_group = nodes.create_debug_group()
mod.node_group.nodes["Object Info"].inputs["Object"].default_value = obj

# need to use 'evaluate' otherwise the modifiers won't be taken into account
return evaluate_object(debug_obj)
return bob.evaluate().object


def create_data_object(array, collection=None, name="DataObject", world_scale=0.01):
Expand Down
4 changes: 2 additions & 2 deletions molecularnodes/entities/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@ def list_attributes(cls, evaluate=False) -> list | None:
warnings.warn("No object created")
return None
if evaluate:
return list(bl.mesh.evaluate_object(cls.object).data.attributes.keys())
return list(cls.bob.evaluate().attributes.keys())

return list(cls.object.data.attributes.keys())
return list(cls.bob.attributes.keys())
12 changes: 5 additions & 7 deletions tests/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,25 +272,23 @@ def test_node_topology(snapshot_custom: NumpySnapshotExtension, code, node_name)


def test_topo_bonds():
mol = mn.entities.fetch(
"1BNA", del_solvent=True, style=None, cache_dir=data_dir
).object
group = nodes.get_mod(mol).node_group = nodes.new_group()
mol = mn.entities.fetch("1BNA", del_solvent=True, style=None, cache_dir=data_dir)
group = nodes.get_mod(mol.object).node_group = nodes.new_group()

# add the node that will break bonds, set the cutoff to 0
node_break = nodes.add_custom(group, "Topology Break Bonds")
nodes.insert_last_node(group, node=node_break)
node_break.inputs["Cutoff"].default_value = 0

# compare the number of edges before and after deleting them with
bonds = mol.data.edges
no_bonds = mn.blender.mesh.evaluate_object(mol).data.edges
bonds = mol.object.data.edges
no_bonds = mol.evaluate().object.data.edges
assert len(bonds) > len(no_bonds)
assert len(no_bonds) == 0

# add the node to find the bonds, and ensure the number of bonds pre and post the nodes
# are the same (other attributes will be different, but for now this is good)
node_find = nodes.add_custom(group, "Topology Find Bonds")
nodes.insert_last_node(group, node=node_find)
bonds_new = mn.blender.mesh.evaluate_object(mol).data.edges
bonds_new = mol.evaluate().edges
assert len(bonds) == len(bonds_new)

0 comments on commit 2048c8b

Please sign in to comment.