Skip to content

Commit

Permalink
Merge branch 'main' into docs-example-listing
Browse files Browse the repository at this point in the history
  • Loading branch information
BradyAJohnston authored Dec 1, 2024
2 parents 0702b16 + c3f4d9a commit e21e931
Show file tree
Hide file tree
Showing 42 changed files with 32,396 additions and 2,275 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/test-addon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
max-parallel: 4
fail-fast: false
matrix:
blender-version: ["4.2"]
version: ["4.2", "4.3"]
os: [ubuntu-latest, macos-14, windows-latest]
steps:
- uses: actions/checkout@v4
Expand All @@ -32,7 +32,7 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
if [[ ! -f ./blender.tar.xz ]]; then
wget -nv https://download.blender.org/release/Blender4.2/blender-4.2.0-linux-x64.tar.xz -O ./blender.tar.xz
wget -nv https://download.blender.org/release/Blender${{ matrix.version }}/blender-${{ matrix.version }}.0-linux-x64.tar.xz -O ./blender.tar.xz
fi
mkdir -p ./blender
ls -lrta
Expand All @@ -45,33 +45,33 @@ jobs:
- name: Test in Blender MacOS ARM
if: matrix.os == 'macos-14'
run: |
curl -L -o blender.dmg https://download.blender.org/release/Blender4.2/blender-4.2.0-macos-arm64.dmg
curl -L -o blender.dmg https://download.blender.org/release/Blender${{ matrix.version }}/blender-${{ matrix.version }}.0-macos-arm64.dmg
hdiutil attach blender.dmg
cp -R /Volumes/Blender/Blender.app /Applications/
hdiutil detach /Volumes/Blender
/Applications/Blender.app/Contents/MacOS/Blender --version
/Applications/Blender.app/Contents/MacOS/Blender -b --python tests/install.py
/Applications/Blender.app/Contents/MacOS/Blender -b --python tests/run.py -- -v tests/
- name: Test in Blender Windows
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
Invoke-WebRequest -Uri "https://download.blender.org/release/Blender4.2/blender-4.2.0-windows-x64.zip" -OutFile "blender.zip"
Invoke-WebRequest -Uri "https://download.blender.org/release/Blender${{ matrix.version }}/blender-${{ matrix.version }}.0-windows-x64.zip" -OutFile "blender.zip"
Expand-Archive -Path "blender.zip" -DestinationPath "blender"
.\blender\blender-4.2.0-windows-x64\blender.exe --version
.\blender\blender-4.2.0-windows-x64\blender.exe -b --python tests/install.py
.\blender\blender-4.2.0-windows-x64\blender.exe -b --python tests/run.py -- -v tests/
$blenderPath = Get-ChildItem -Path "blender" -Directory | Select-Object -First 1
.\blender\blender-${{ matrix.version }}.0-windows-x64\blender.exe --version
.\blender\blender-${{ matrix.version }}.0-windows-x64\blender.exe -b --python tests/install.py
.\blender\blender-${{ matrix.version }}.0-windows-x64\blender.exe -b --python tests/run.py -- -v tests/
- name: Expose coverage as a CI download
uses: actions/upload-artifact@v4
if: matrix.os == 'ubuntu-latest'
if: matrix.os == 'ubuntu-latest' && matrix.version == '4.2'
with:
name: coverage.xml
path: coverage.xml

- name: Upload coverage reports to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v3


19 changes: 10 additions & 9 deletions molecularnodes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

import bpy
from bpy.app.handlers import frame_change_post, load_post, save_post

from bpy.props import PointerProperty, CollectionProperty
from .handlers import update_trajectories
from . import entities, operators, props, session, ui
from .utils import add_current_module_to_path
from .ui import pref
Expand All @@ -24,8 +25,8 @@
ui.CLASSES
+ operators.CLASSES
+ entities.CLASSES
+ props.CLASSES
+ [
props.MolecularNodesObjectProperties,
MN_PT_Scene,
]
+ pref.CLASSES
Expand Down Expand Up @@ -56,14 +57,13 @@ def register():

save_post.append(session._pickle)
load_post.append(session._load)
frame_change_post.append(entities.trajectory.handlers.update_trajectories)
frame_change_post.append(update_trajectories)

bpy.types.Scene.MNSession = session.MNSession()
bpy.types.Object.mn = bpy.props.PointerProperty(
type=props.MolecularNodesObjectProperties
)
bpy.types.Object.mn_trajectory_selections = bpy.props.CollectionProperty(
type=entities.trajectory.selections.TrajectorySelectionItem
bpy.types.Object.mn = PointerProperty(type=props.MolecularNodesObjectProperties)
bpy.types.Scene.mn = PointerProperty(type=props.MolecularNodesSceneProperties)
bpy.types.Object.mn_trajectory_selections = CollectionProperty(
type=entities.trajectory.props.TrajectorySelectionItem
)


Expand All @@ -81,7 +81,8 @@ def unregister():

save_post.remove(session._pickle)
load_post.remove(session._load)
frame_change_post.remove(entities.trajectory.handlers.update_trajectories)
frame_change_post.remove(update_trajectories)
del bpy.types.Scene.MNSession
del bpy.types.Scene.mn
del bpy.types.Object.mn
del bpy.types.Object.mn_trajectory_selections
Binary file modified molecularnodes/assets/MN_data_file_4.2.blend
Binary file not shown.
Binary file modified molecularnodes/assets/template/startup.blend
Binary file not shown.
52 changes: 29 additions & 23 deletions molecularnodes/blender/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def set_selection(group, node, selection):


def create_debug_group(name="MolecularNodesDebugGroup"):
group = new_group(name=name, fallback=False)
group = new_tree(name=name, fallback=False)
info = group.nodes.new("GeometryNodeObjectInfo")
group.links.new(info.outputs["Geometry"], group.nodes["Group Output"].inputs[0])
return group
Expand Down Expand Up @@ -231,7 +231,9 @@ def MN_micrograph_material():
return bpy.data.materials[mat_name]


def new_group(name="Geometry Nodes", geometry=True, fallback=True):
def new_tree(
name: str = "Geometry Nodes", geometry: bool = True, fallback: bool = True
) -> bpy.types.GeometryNodeTree:
group = bpy.data.node_groups.get(name)
# if the group already exists, return it and don't create a new one
if group and fallback:
Expand Down Expand Up @@ -307,7 +309,7 @@ def create_starting_nodes_starfile(object, n_images=1):
node_name = f"MN_starfile_{object.name}"

# create a new GN node group, specific to this particular molecule
group = new_group(node_name)
group = new_tree(node_name)
node_mod.node_group = group
link = group.links.new

Expand All @@ -327,7 +329,7 @@ def create_starting_nodes_density(object, threshold=0.8, style="density_surface"
node_name = f"MN_density_{object.name}"

# create a new GN node group, specific to this particular molecule
group = new_group(node_name, fallback=False)
group = new_tree(node_name, fallback=False)
link = group.links.new
mod.node_group = group

Expand All @@ -345,7 +347,12 @@ def create_starting_nodes_density(object, threshold=0.8, style="density_surface"


def create_starting_node_tree(
object, coll_frames=None, style="spheres", name=None, color="common"
object: bpy.types.Object,
coll_frames: bpy.types.Collection | None = None,
style: str = "spheres",
name: str = None,
color: str = "common",
is_modifier: bool = True,
):
"""
Create a starting node tree for the inputted object.
Expand Down Expand Up @@ -375,37 +382,36 @@ def create_starting_node_tree(

# create a new GN node group, specific to this particular molecule
mod = get_mod(object)
group = new_group(name)
link = group.links.new
mod.node_group = group
tree = new_tree(name)
tree.is_modifier = is_modifier
link = tree.links.new
mod.node_group = tree

# move the input and output nodes for the group
node_input = get_input(group)
node_output = get_output(group)
node_input = get_input(tree)
node_output = get_output(tree)
node_input.location = [0, 0]
node_output.location = [700, 0]

node_style = add_custom(group, styles_mapping[style], [450, 0])
node_style = add_custom(tree, styles_mapping[style], [450, 0])
link(node_style.outputs[0], node_output.inputs[0])
link(node_input.outputs[0], node_style.inputs[0])

# if requested, setup the nodes for generating colors in the node tree
if color is not None:
if color == "common":
node_color_set = add_custom(group, "Set Color", [200, 0])
node_color_common = add_custom(group, "Color Common", [-50, -150])
node_random_color = add_custom(
group, "Color Attribute Random", [-300, -150]
)
node_color_set = add_custom(tree, "Set Color", [200, 0])
node_color_common = add_custom(tree, "Color Common", [-50, -150])
node_random_color = add_custom(tree, "Color Attribute Random", [-300, -150])

link(node_input.outputs["Geometry"], node_color_set.inputs[0])
link(node_random_color.outputs["Color"], node_color_common.inputs["Carbon"])
link(node_color_common.outputs[0], node_color_set.inputs["Color"])
link(node_color_set.outputs[0], node_style.inputs[0])
to_animate = node_color_set
elif color.lower() == "plddt":
node_color_set = add_custom(group, "Set Color", [200, 0])
node_color_plddt = add_custom(group, "Color pLDDT", [-50, -150])
node_color_set = add_custom(tree, "Set Color", [200, 0])
node_color_plddt = add_custom(tree, "Color pLDDT", [-50, -150])

link(node_input.outputs["Geometry"], node_color_set.inputs["Atoms"])
link(node_color_plddt.outputs[0], node_color_set.inputs["Color"])
Expand All @@ -420,8 +426,8 @@ def create_starting_node_tree(
node_output.location = [1100, 0]
node_style.location = [800, 0]

node_animate_frames = add_custom(group, "Animate Frames", [500, 0])
node_animate = add_custom(group, "Animate Value", [500, -300])
node_animate_frames = add_custom(tree, "Animate Frames", [500, 0])
node_animate = add_custom(tree, "Animate Value", [500, -300])

node_animate_frames.inputs["Frames"].default_value = coll_frames
node_animate.inputs["Value Max"].default_value = len(coll_frames.objects) - 1
Expand Down Expand Up @@ -451,7 +457,7 @@ def split_geometry_to_instances(name, iter_list=("A", "B", "C"), attribute="chai
define how many times to create the required nodes.
"""
group = new_group(name)
group = new_tree(name)
node_input = get_input(group)
node_output = get_output(group)

Expand Down Expand Up @@ -515,7 +521,7 @@ def create_assembly_node_tree(
if existing_node_tree:
return existing_node_tree

tree: bpy.types.NodeTree = new_group(name=node_group_name)
tree: bpy.types.NodeTree = new_tree(name=node_group_name)
link = tree.links.new

node_split = add_custom(tree, "Split to Centred Instances", [-150, 0])
Expand Down Expand Up @@ -683,7 +689,7 @@ def custom_iswitch(
return tree

socket_type = socket_types[dtype]
tree = new_group(name, geometry=False, fallback=False)
tree = new_tree(name, geometry=False, fallback=False)

# try creating the node group, otherwise on fail cleanup the created group and
# report the error
Expand Down
22 changes: 11 additions & 11 deletions molecularnodes/blender_manifest.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
schema_version = "1.0.0"

id = "molecularnodes"
version = "4.2.8"
version = "4.2.9"
name = "Molecular Nodes"
tagline = "A toolbox for molecular import and animation in Blender"
maintainer = "Brady Johnston<[email protected]>"
Expand Down Expand Up @@ -35,16 +35,16 @@ wheels = [
"./wheels/biotite-0.41.2-cp311-cp311-macosx_11_0_arm64.whl",
"./wheels/biotite-0.41.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"./wheels/biotite-0.41.2-cp311-cp311-win_amd64.whl",
"./wheels/contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl",
"./wheels/contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl",
"./wheels/contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"./wheels/contourpy-1.3.0-cp311-cp311-win_amd64.whl",
"./wheels/contourpy-1.3.1-cp311-cp311-macosx_10_9_x86_64.whl",
"./wheels/contourpy-1.3.1-cp311-cp311-macosx_11_0_arm64.whl",
"./wheels/contourpy-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"./wheels/contourpy-1.3.1-cp311-cp311-win_amd64.whl",
"./wheels/cycler-0.12.1-py3-none-any.whl",
"./wheels/fasteners-0.19-py3-none-any.whl",
"./wheels/fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl",
"./wheels/fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl",
"./wheels/fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"./wheels/fonttools-4.54.1-cp311-cp311-win_amd64.whl",
"./wheels/fonttools-4.55.0-cp311-cp311-macosx_10_9_universal2.whl",
"./wheels/fonttools-4.55.0-cp311-cp311-macosx_10_9_x86_64.whl",
"./wheels/fonttools-4.55.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"./wheels/fonttools-4.55.0-cp311-cp311-win_amd64.whl",
"./wheels/joblib-1.4.2-py3-none-any.whl",
"./wheels/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl",
"./wheels/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl",
Expand All @@ -62,7 +62,7 @@ wheels = [
"./wheels/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"./wheels/msgpack-1.1.0-cp311-cp311-win_amd64.whl",
"./wheels/networkx-3.4.2-py3-none-any.whl",
"./wheels/packaging-24.1-py3-none-any.whl",
"./wheels/packaging-24.2-py3-none-any.whl",
"./wheels/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl",
"./wheels/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl",
"./wheels/pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
Expand All @@ -81,7 +81,7 @@ wheels = [
"./wheels/six-1.16.0-py2.py3-none-any.whl",
"./wheels/starfile-0.5.6-py3-none-any.whl",
"./wheels/threadpoolctl-3.5.0-py3-none-any.whl",
"./wheels/tqdm-4.66.6-py3-none-any.whl",
"./wheels/tqdm-4.67.1-py3-none-any.whl",
"./wheels/typing_extensions-4.12.2-py3-none-any.whl",
"./wheels/tzdata-2024.2-py2.py3-none-any.whl",
]
Expand Down
6 changes: 3 additions & 3 deletions molecularnodes/bpyd/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,14 @@ def list_attributes(
A list of attribute names if the molecule object exists, None otherwise.
"""
if evaluate:
strings = list(self.evaluate().attributes.keys())
strings = list(self.evaluate().object.data.attributes.keys())
else:
strings = list(self.object.attributes.keys())
strings = list(self.object.data.attributes.keys())

if not drop_hidden:
return strings
else:
return filter(lambda x: not x.startswith("."), strings)
return [x for x in strings if not x.startswith(".")]

def __len__(self) -> int:
"""
Expand Down
2 changes: 1 addition & 1 deletion molecularnodes/entities/ensemble/cellpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def _create_data_object(self, name="DataObject"):
def _setup_node_tree(self, name="CellPack", fraction=1.0, as_points=False):
mod = bl.nodes.get_mod(self.data_object)

group = bl.nodes.new_group(name=f"MN_ensemble_{name}", fallback=False)
group = bl.nodes.new_tree(name=f"MN_ensemble_{name}", fallback=False)
mod.node_group = group

node_pack = bl.nodes.add_custom(group, "Ensemble Instance", location=[-100, 0])
Expand Down
19 changes: 9 additions & 10 deletions molecularnodes/entities/ensemble/cif.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,15 @@ def _get_structure(self, extra_fields: str = None, sec_struct=True, bonds=True):
# which can be extracted with the get_component()
try:
array = pdbx.get_structure(self.file, extra_fields=extra_fields)
try:
array.set_annotation(
"sec_struct", _get_secondary_structure(array, self.file)
)
except KeyError:
warnings.warn("No secondary structure information.")
try:
array.set_annotation("entity_id", _get_entity_id(array, self.file))
except KeyError:
warnings.warn("Non entity_id information.")
annotations = {
"sec_struct": _get_secondary_structure,
"entity_id": _get_entity_id,
}
for key, func in annotations.items():
try:
array.set_annotation(key, func(array, self.file))
except KeyError:
pass

except InvalidFileError:
array = pdbx.get_component(self.file)
Expand Down
4 changes: 4 additions & 0 deletions molecularnodes/entities/molecule/molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ def n_models(self):
else:
return self.array.shape[0]

@property
def tree(self) -> bpy.types.GeometryNodeTree:
return self.object.modifiers["MolecularNodes"].node_group

@property
def chain_ids(self) -> Optional[list]:
"""
Expand Down
Loading

0 comments on commit e21e931

Please sign in to comment.