Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
jonmatthis committed Nov 5, 2023
2 parents 7272637 + 7bc035f commit 10eca86
Show file tree
Hide file tree
Showing 28 changed files with 316 additions and 150 deletions.
5 changes: 4 additions & 1 deletion ajc27_freemocap_blender_addon/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#######################################################################
import logging
import sys
from pathlib import Path

PACKAGE_ROOT_PATH = str(Path(__file__).parent)

root = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
Expand Down Expand Up @@ -58,7 +61,7 @@ def register():
print(f"Registering class {cls.__name__}")
bpy.utils.register_class(cls)

print(f"Registering property group FMC_ADAPTER_PROPERTIES")
print("Registering property group FMC_ADAPTER_PROPERTIES")

from .blender_interface import FMC_ADAPTER_PROPERTIES
bpy.types.Scene.fmc_adapter_properties = bpy.props.PointerProperty(type=FMC_ADAPTER_PROPERTIES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def draw(self, context):

self._save_data_to_disk_panel(fmc_adapter_tool, layout)

self._center_of_mass_trail_panel(fmc_adapter_tool, layout)

# self._load_data_panel(fmc_adapter_tool, layout)
#
# self._reduce_bone_dispersion_panel(fmc_adapter_tool, layout)
Expand All @@ -34,6 +36,12 @@ def draw(self, context):
# self._add_body_mesh_panel(fmc_adapter_tool, layout)
#
# self._fbx_export_panel(layout)
def _center_of_mass_trail_panel(self, fmc_adapter_tool, layout):
box = layout.box()
box.label(text="Center of Mass Trail:")
box.prop(fmc_adapter_tool, "center_of_mass_past_frames", text="Past Frames")
box.prop(fmc_adapter_tool, "center_of_mass_future_frames", text="Future Frames")
box.prop(fmc_adapter_tool, "center_of_mass_size_fall_off", text="Size Fall Off")

def _clear_scene_button(self, layout):
# Clear scene button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import bpy
from bpy.types import Operator

from ...core_functions.mesh.attach_mesh_to_rig import attach_mesh_to_rig
from ...core_functions.meshes.attach_mesh_to_rig import attach_mesh_to_rig
from ...core_functions.empties.reorient_empties import reorient_empties
from ...core_functions.rig.add_rig import add_rig

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def execute(self, context):
controller = MainController(recording_path=recording_path,
save_path=str(Path(recording_path)/(Path(recording_path).stem+".blend")),
config=config)
fmc_adapter_tool.data_parent_empty = controller.data_parent_object
controller.run_all()
except Exception as e:
print(f"Failed to run main_controller.run_all() with config:{config}: `{e}`")
Expand Down
28 changes: 24 additions & 4 deletions ajc27_freemocap_blender_addon/blender_interface/properties.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import logging

import bpy
from bpy.props import StringProperty, BoolProperty

import sys



class FMC_ADAPTER_PROPERTIES(bpy.types.PropertyGroup):
print("Initializing FMC_ADAPTER_PROPERTIES class...")


data_parent_empty: bpy.props.PointerProperty(
name="FreeMoCap data parent empty",
description="Empty that serves as parent for all the freemocap empties",
type=bpy.types.Object,
poll=lambda self, object: object.type == 'EMPTY',
poll=lambda self, object_in: object_in.type == 'EMPTY',
)

recording_path: StringProperty(
Expand All @@ -22,6 +21,27 @@ class FMC_ADAPTER_PROPERTIES(bpy.types.PropertyGroup):
default="",
subtype='FILE_PATH',
)
center_of_mass_past_frames: bpy.props.IntProperty(
name="Past Frames",
description="Number of past data frames of the center of mass trajectory to draw",
default=30,
min=0,
)

center_of_mass_future_frames: bpy.props.IntProperty(
name="Future Frames",
description="Number of future data frames to draw",
default=30,
min=0,
)

center_of_mass_size_fall_off: bpy.props.FloatProperty(
name="Future Frames",
description="How quickly the size of the center of mass trail falls off down to minimum (1.0 drops immediately to minimum, 0.0 never drops)",
default=0.5,
max=1.0,
min=0.0
)

# Show Options Booleans
show_reorient_empties_options: BoolProperty(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ def enforce_rigid_bones(handler: FreemocapDataHandler,
handler.set_trajectory(name=name, data=trajectory)

handler.mark_processing_stage(name='enforced_rigid_bones',
metadata={'bones': updated_bones,
metadata={"bone_data": updated_bones,
"body_dimensions": calculate_body_dimensions(bones_info=updated_bones),
'hierarchy': MEDIAPIPE_HIERARCHY},
"skeleton_hierarchy": MEDIAPIPE_HIERARCHY},
)
return handler

Expand Down
89 changes: 75 additions & 14 deletions ajc27_freemocap_blender_addon/core_functions/main_controller.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import traceback
from pathlib import Path
from typing import List

from .mesh.skelly_mesh.attach_skelly_mesh import attach_skelly_mesh_to_rig
from .meshes.center_of_mass.create_center_of_mass_mesh import create_center_of_mass_mesh
from .meshes.center_of_mass.create_center_of_mass_trails import create_center_of_mass_trails
from .meshes.skelly_mesh.attach_skelly_mesh import attach_skelly_mesh_to_rig
from .rig.save_bone_and_joint_angles_from_rig import save_bone_and_joint_angles_from_rig
from ..core_functions.bones.enforce_rigid_bones import enforce_rigid_bones
from ..core_functions.empties.creation.create_freemocap_empties import (
Expand All @@ -19,7 +22,7 @@
)
from ..core_functions.load_data.load_freemocap_data import load_freemocap_data
from ..core_functions.load_data.load_videos import load_videos
from ..core_functions.mesh.attach_mesh_to_rig import attach_mesh_to_rig
from ..core_functions.meshes.attach_mesh_to_rig import attach_mesh_to_rig
from ..core_functions.rig.add_rig import add_rig
from ..core_functions.setup_scene.make_parent_empties import (
create_parent_empty,
Expand All @@ -35,6 +38,12 @@ class MainController:

def __init__(self, recording_path: str, save_path: str, config: Config):
self.rig = None
self.empties = None
self._data_parent_object = None
self._empty_parent_object = None
self._rigid_body_meshes_parent_object = None
self._video_parent_object = None

self.config = config

self.recording_path = recording_path
Expand All @@ -48,24 +57,45 @@ def __init__(self, recording_path: str, save_path: str, config: Config):
)
self.empties = None

@property
def data_parent_object(self):
return self._data_parent_object

@property
def empty_names(self) -> List[str]:
if self.empties is None:
raise ValueError("Empties have not been created yet!")
empty_names = []

def get_empty_names_from_dict(dictionary):
for key, value in dictionary.items():
if isinstance(value, dict):
get_empty_names_from_dict(value) #recursion, baby!
else:
empty_names.append(key)

get_empty_names_from_dict(self.empties)

return empty_names

def _create_parent_empties(self):
self.data_parent_object = create_parent_empty(name=self.origin_name,
type="ARROWS")
self._data_parent_object = create_parent_empty(name=self.origin_name,
type="ARROWS")
self._empty_parent_object = create_parent_empty(
name=f"empties",
parent_object=self.data_parent_object,
parent_object=self._data_parent_object,
type="PLAIN_AXES",
scale=(0.3, 0.3, 0.3),
)
self._rigid_body_meshes_parent_object = create_parent_empty(
name=f"rigid_body_meshes",
parent_object=self.data_parent_object,
parent_object=self._data_parent_object,
type="CUBE",
scale=(0.2, 0.2, 0.2),
)
self._video_parent_object = create_parent_empty(
name=f"videos",
parent_object=self.data_parent_object,
parent_object=self._data_parent_object,
type="SPHERE",
scale=(0.1, 0.1, 0.1),
)
Expand Down Expand Up @@ -157,10 +187,10 @@ def add_rig(self):
try:
print("Adding rig...")
self.rig = add_rig(
empties=self.empties,
bones=self.freemocap_data_handler.metadata["bones"],
empty_names=self.empty_names,
bone_data=self.freemocap_data_handler.metadata["bone_data"],
rig_name=self.rig_name,
parent_object=self.data_parent_object,
parent_object=self._data_parent_object,
keep_symmetry=self.config.add_rig.keep_symmetry,
add_fingers_constraints=self.config.add_rig.add_fingers_constraints,
use_limit_rotation=self.config.add_rig.use_limit_rotation,
Expand Down Expand Up @@ -221,6 +251,32 @@ def attach_skelly_mesh_to_rig(self):
print(e)
raise e

def create_center_of_mass_mesh(self):

try:
print("Adding Center of Mass Mesh!!! :D")
create_center_of_mass_mesh(
center_of_mass_xyz = self.freemocap_data_handler.center_of_mass_xyz,
center_of_mass_empty = self.freemocap_data_handler.center_of_mass_empty,
)
except Exception as e:
print(f"Failed to attach mesh to rig: {e}")
print(e)
raise e

def create_center_of_mass_trails(self):

try:
print("Adding Center of Mass Mesh!!! :D")
create_center_of_mass_trails(
center_of_mass_xyz = self.freemocap_data_handler.center_of_mass_xyz,
center_of_mass_empty = self.freemocap_data_handler.center_of_mass_empty,
)
except Exception as e:
print(f"Failed to attach mesh to rig: {e}")
print(e)
raise e

def add_videos(self):
try:
print("Loading videos as planes...")
Expand All @@ -245,10 +301,10 @@ def setup_scene(self):
if space.type == "VIEW_3D": # check if space is a 3D view
space.shading.type = "MATERIAL"

# self.data_parent_object.hide_set(True)
# self._empty_parent_object.hide_set(True)
# self._rigid_body_meshes_parent_object.hide_set(True)
# self._video_parent_object.hide_set(True)
self.data_parent_object.hide_set(True)
self._empty_parent_object.hide_set(True)
self._rigid_body_meshes_parent_object.hide_set(True)
self._video_parent_object.hide_set(True)


def save_blender_file(self):
Expand All @@ -260,17 +316,22 @@ def save_blender_file(self):

def run_all(self):
print("Running all stages...")

#Pure python stuff
self.load_freemocap_data()
self.calculate_virtual_trajectories()
self.put_data_in_inertial_reference_frame()
self.enforce_rigid_bones()
self.fix_hand_data()
self.save_data_to_disk()

#Blender stuff
self.create_empties()
self.add_rig()
self.save_bone_and_joint_data_from_rig()
self.attach_rigid_body_mesh_to_rig()
self.attach_skelly_mesh_to_rig()
# self.create_center_of_mass_mesh()
self.add_videos()
self.setup_scene()
self.save_blender_file()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import numpy as np
import bpy

def create_center_of_mass_mesh(center_of_mass_xyz:np.ndarray,
center_of_mass_empty: bpy.types.Object):
# Create a mesh object for the center of mass, with a default sphere mesh that is a sphere with radius .05 and a material that is a "checkboard" pattern with a scale of 2.0 and colors that are Blue and Yellow
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.05, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
center_of_mass_mesh = bpy.context.active_object
center_of_mass_mesh.name = "center_of_mass_mesh"
center_of_mass_mesh.data.name = "center_of_mass_mesh_data"
center_of_mass_mesh.location = center_of_mass_xyz
center_of_mass_mesh.parent = center_of_mass_empty

# Create a material for the center of mass mesh
bpy.ops.material.new(name="center_of_mass_material")
material = bpy.data.materials["center_of_mass_material"]
material.use_nodes = True
# Get the material nodes
nodes = material.node_tree.nodes
# Remove the default 'Principled BSDF'
nodes.remove(nodes['Principled BSDF'])
# Create a new 'Checker Texture' node
checker_node = nodes.new(type='ShaderNodeTexChecker')




Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def create_center_of_mass_trails(center_of_mass_xyz, center_of_mass_empty):
pass
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

import bpy

SKELLY_MESH_PATH = r"C:\Users\jonma\github_repos\freemocap_organization\ajc27_freemocap_blender_addon\ajc27_freemocap_blender_addon\assets\skelly_lowpoly_mesh.fbx"
from ajc27_freemocap_blender_addon import PACKAGE_ROOT_PATH
from pathlib import Path

SKELLY_MESH_PATH = str(Path(PACKAGE_ROOT_PATH) / "assets" / "skelly_lowpoly_mesh.fbx")

def attach_skelly_mesh_to_rig(rig: bpy.types.Object,
body_dimensions: Dict[str, float],
Expand Down
Loading

0 comments on commit 10eca86

Please sign in to comment.