Skip to content

Commit

Permalink
Weekly updates (#5)
Browse files Browse the repository at this point in the history
* restructure to support additional file formats

* update for dim3 template

* rename simloader to bseq

* minor fix

* add notes

* use blender driver system to control frames

* small update with frame driver

* disbale the function when not in object mode

* small fix

* rewrite edit

* add global settings for refresh
  • Loading branch information
losanc authored Sep 12, 2022
1 parent 7c090ec commit f02ee8a
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 47 deletions.
28 changes: 5 additions & 23 deletions bseq/__init__.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,18 @@
from .operators import BSEQ_OT_load, BSEQ_OT_edit, BSEQ_OT_resetpt, BSEQ_OT_resetmesh, BSEQ_OT_resetins,BSEQ_OT_set_as_split_norm,BSEQ_OT_remove_split_norm,BSEQ_OT_disable_selected,BSEQ_OT_enable_selected,BSEQ_OT_refresh_seq
from .properties import BSEQ_scene_property, BSEQ_obj_property,BSEQ_mesh_property
from bseq.utils import refresh_obj
from .operators import BSEQ_OT_load, BSEQ_OT_edit, BSEQ_OT_resetpt, BSEQ_OT_resetmesh, BSEQ_OT_resetins, BSEQ_OT_set_as_split_norm, BSEQ_OT_remove_split_norm, BSEQ_OT_disable_selected, BSEQ_OT_enable_selected, BSEQ_OT_refresh_seq
from .properties import BSEQ_scene_property, BSEQ_obj_property, BSEQ_mesh_property
from .panels import BSEQ_UL_Obj_List, BSEQ_List_Panel, BSEQ_Settings, BSEQ_Import, BSEQ_Templates, BSEQ_UL_Att_List, draw_template
from .messenger import subscribe_to_selected, unsubscribe_to_selected
import bpy
from bpy.app.handlers import persistent
from .importer import update_obj
from datetime import datetime


def print_information(scene):
if not bpy.context.scene.BSEQ.print:
return
now = datetime.now()
path = bpy.context.scene.render.filepath
path = bpy.path.abspath(path)
filepath = path + '/bseq_' + now.strftime("%Y-%m-%d_%H-%M")
with open(filepath, 'w') as file:
file.write("Render Time: {}\n".format(now.strftime("%Y-%m-%d_%H-%M")))
file.write("bseq Objects in the scene:\n\n")
for obj in bpy.data.objects:
bseq_prop = obj.BSEQ
if bseq_prop.init:
file.write("Object name: {}\n".format(obj.name))
file.write("Is it being animated: {}\n".format(bseq_prop.enabled))
file.write("Filepath: {}\n".format(bseq_prop.pattern))
file.write("Is it relative path: {}\n".format(bseq_prop.use_relative))
file.write("\n\n")
from .globals import *


@persistent
def BSEQ_initialize(scene):
if update_obj not in bpy.app.handlers.frame_change_post:
bpy.app.handlers.frame_change_post.append(auto_refresh)
bpy.app.handlers.frame_change_post.append(update_obj)
subscribe_to_selected()
if print_information not in bpy.app.handlers.render_init:
Expand Down
5 changes: 4 additions & 1 deletion bseq/callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ def update_selected_obj_num(self, context):


def poll_material(self, material):
return not material.is_grease_pencil
return not material.is_grease_pencil

def poll_edit_obj(self, object):
return object.BSEQ.init
41 changes: 41 additions & 0 deletions bseq/globals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# here are the implementations of global settings

import bpy
from datetime import datetime
import os
from .utils import refresh_obj

def print_information(scene):
if not bpy.context.scene.BSEQ.print:
return
now = datetime.now()
path = bpy.context.scene.render.filepath
path = bpy.path.abspath(path)
if not os.path.isdir(path):
# by default, path is '/tmp', and it does not exist on windows system
return
filepath = path + '/bseq_' + now.strftime("%Y-%m-%d_%H-%M")
with open(filepath, 'w') as file:
file.write("Render Time: {}\n".format(now.strftime("%Y-%m-%d_%H-%M")))
file.write("bseq Objects in the scene:\n\n")
for obj in bpy.data.objects:
bseq_prop = obj.BSEQ
if bseq_prop.init:
file.write("Object name: {}\n".format(obj.name))
file.write("Is it being animated: {}\n".format(bseq_prop.enabled))
file.write("Filepath: {}\n".format(bseq_prop.pattern))
file.write("Is it relative path: {}\n".format(bseq_prop.use_relative))
file.write("\n\n")


def auto_refresh(scene, depsgraph=None):
if not bpy.context.scene.BSEQ.auto_refresh:
return
for obj in bpy.data.objects:
if obj.BSEQ.init == False:
continue
if obj.BSEQ.enabled == False:
continue
if obj.mode != "OBJECT":
continue
refresh_obj(obj)
8 changes: 5 additions & 3 deletions bseq/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ def create_obj(fileseq, use_relaitve, transform_matrix=Matrix([[1, 0, 0, 0], [0,
object.BSEQ.init = True
object.BSEQ.enabled = enabled
object.matrix_world = transform_matrix
driver = object.driver_add("BSEQ.frame")
driver.driver.expression = 'frame'
if enabled:
update_mesh(meshio_mesh, object.data)
bpy.context.collection.objects.link(object)
Expand All @@ -172,16 +174,16 @@ def create_obj(fileseq, use_relaitve, transform_matrix=Matrix([[1, 0, 0, 0], [0,


def update_obj(scene, depsgraph=None):
# TODO if bpy in edit mode, then return

current_frame = bpy.context.scene.frame_current

for obj in bpy.data.objects:
if obj.BSEQ.init == False:
continue
if obj.BSEQ.enabled == False:
continue
if obj.mode != "OBJECT":
continue

current_frame = obj.BSEQ.frame
meshio_mesh = None
pattern = obj.BSEQ.pattern
if obj.BSEQ.use_relative:
Expand Down
3 changes: 2 additions & 1 deletion bseq/messenger.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ def selected_callback():
bpy.context.scene.BSEQ.selected_obj_deselectall_flag = False
bpy.context.scene.BSEQ.selected_obj_num = idx
bpy.context.scene.BSEQ.selected_obj_deselectall_flag = True

if bpy.context.active_object.BSEQ.init:
bpy.context.scene.BSEQ.edit_obj = bpy.context.active_object

def subscribe_to_selected():
import bseq
Expand Down
25 changes: 9 additions & 16 deletions bseq/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import fileseq
from .messenger import *
import traceback
from .utils import show_message_box
from .utils import refresh_obj, show_message_box
from .importer import create_obj
import numpy as np

Expand Down Expand Up @@ -79,10 +79,12 @@ def execute(self, context):
return {"CANCELLED"}

sim_loader = context.scene.BSEQ

# logic here
# it seems quite simple task, no need to create a function(for now)
if sim_loader.selected_obj_num >= len(bpy.data.objects):
obj = sim_loader.edit_obj
if not obj:
return {"CANCELLED"}
obj = bpy.data.objects[sim_loader.selected_obj_num]
if importer_prop.relative:
obj.BSEQ.pattern = bpy.path.relpath(str(fs))
else:
Expand Down Expand Up @@ -110,7 +112,7 @@ def execute(self, context):
gn = obj.modifiers.new("BSEQ_GeometryNodse", "NODES")
# change starting from blender 3.2
# https://developer.blender.org/rB08b4b657b64f
if bpy.app.version >= (3,2,0):
if bpy.app.version >= (3, 2, 0):
bpy.ops.node.new_geometry_node_group_assign()
gn.node_group.nodes.new('GeometryNodeMeshToPoints')
set_material = gn.node_group.nodes.new('GeometryNodeSetMaterial')
Expand Down Expand Up @@ -145,7 +147,7 @@ def execute(self, context):
gn = obj.modifiers.new("BSEQ_GeometryNodse", "NODES")
# change starting from blender 3.2
# https://developer.blender.org/rB08b4b657b64f
if bpy.app.version >= (3,2,0):
if bpy.app.version >= (3, 2, 0):
bpy.ops.node.new_geometry_node_group_assign()
bpy.ops.object.modifier_move_to_index(modifier=gn.name, index=0)
return {"FINISHED"}
Expand All @@ -170,7 +172,7 @@ def execute(self, context):
gn = obj.modifiers.new("BSEQ_GeometryNodse", "NODES")
# change starting from blender 3.2
# https://developer.blender.org/rB08b4b657b64f
if bpy.app.version >= (3,2,0):
if bpy.app.version >= (3, 2, 0):
bpy.ops.node.new_geometry_node_group_assign()
nodes = gn.node_group.nodes
links = gn.node_group.links
Expand Down Expand Up @@ -268,15 +270,6 @@ class BSEQ_OT_refresh_seq(bpy.types.Operator):
def execute(self, context):
scene = context.scene
obj = bpy.data.objects[scene.BSEQ.selected_obj_num]

fs = obj.BSEQ.pattern
if obj.BSEQ.use_relative:
fs = bpy.path.abspath(fs)
fs = fileseq.findSequenceOnDisk(fs)
fs = fileseq.findSequenceOnDisk(fs.dirname() + fs.basename() + "@" + fs.extension())
fs = str(fs)
if obj.BSEQ.use_relative:
fs = bpy.path.relpath(fs)
obj.BSEQ.pattern = fs
refresh_obj(obj)

return {"FINISHED"}
11 changes: 9 additions & 2 deletions bseq/panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ def draw_item(self, context, layout, data, item, icon, active_data, active_propn
row.prop(item, "name", text='Name ', emboss=False)
if item.BSEQ.enabled:
row.prop(item.BSEQ, "enabled", text = "ENABLED", icon="PLAY")
row.prop(item.BSEQ, "frame", text = "Current Frame:")
else:
row.prop(item.BSEQ, "enabled", text = "DISABLED", icon="PAUSE")
row.label(text = "Animation Stopped")
else:
# actually, I guess this line of code won't be executed?
layout.label(text="", translate=False, icon_value=icon)
Expand Down Expand Up @@ -71,8 +73,6 @@ def draw(self, context):
row = layout.row()
row.operator("bseq.enableselected", text="Enable Selected")
row.operator("bseq.disableselected", text="Disable Selected")
row = layout.row()
row.operator("sequence.edit", text="Edit Path")
row.operator("bseq.refresh", text="Refresh")


Expand Down Expand Up @@ -193,6 +193,11 @@ def draw(self, context):
col2.prop(importer_prop, "relative", text="")

layout.operator("sequence.load")
split = layout.split()
col1 = split.column()
col2 = split.column()
col1.prop_search(importer_prop, 'edit_obj', bpy.data, 'objects', text="")
col2.operator("sequence.edit")

layout.label(text="Global Settings")
box = layout.box()
Expand All @@ -203,6 +208,8 @@ def draw(self, context):

col1.label(text="Print Sequence Information on Render")
col2.prop(importer_prop, "print", text="")
col1.label(text="Auto refresh all the sequence every frame")
col2.prop(importer_prop, "auto_refresh", text="")


class BSEQ_Templates(bpy.types.Menu):
Expand Down
10 changes: 10 additions & 0 deletions bseq/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,19 @@ class BSEQ_scene_property(bpy.types.PropertyGroup):
poll=poll_material,
)

edit_obj: bpy.props.PointerProperty(
type=bpy.types.Object,
poll=poll_edit_obj,
)

print: bpy.props.BoolProperty(name='print',
description="whether or not to print additional information when rendering",
default=True)

auto_refresh: bpy.props.BoolProperty(name='auto refresh',
description="whether or not to auto refresh all the sequence every frame",
default=False)


class BSEQ_obj_property(bpy.types.PropertyGroup):
init: bpy.props.BoolProperty(default=False)
Expand All @@ -45,6 +54,7 @@ class BSEQ_obj_property(bpy.types.PropertyGroup):
script_name: bpy.props.StringProperty()
use_relative: bpy.props.BoolProperty(default=False)
pattern: bpy.props.StringProperty()
frame: bpy.props.IntProperty()


# set this property for mesh, not object (maybe change later?)
Expand Down
14 changes: 13 additions & 1 deletion bseq/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import bpy

import fileseq

def show_message_box(message="", title="Message Box", icon="INFO"):
'''
Expand All @@ -24,3 +24,15 @@ def stop_animation():
# if playing animation, then stop it, otherwise it will keep showing message box
bpy.ops.screen.animation_cancel()



def refresh_obj(obj):
fs = obj.BSEQ.pattern
if obj.BSEQ.use_relative:
fs = bpy.path.abspath(fs)
fs = fileseq.findSequenceOnDisk(fs)
fs = fileseq.findSequenceOnDisk(fs.dirname() + fs.basename() + "@" + fs.extension())
fs = str(fs)
if obj.BSEQ.use_relative:
fs = bpy.path.relpath(fs)
obj.BSEQ.pattern = fs

0 comments on commit f02ee8a

Please sign in to comment.