Compare commits
11 Commits
204-animat
...
207-reposi
Author | SHA1 | Date | |
---|---|---|---|
de1e684b3c | |||
d87730cffb | |||
3f005b86ab | |||
5098e5135d | |||
37cfed489c | |||
9003abcd18 | |||
a199e0df00 | |||
3774419b7e | |||
3e552cb406 | |||
9f381b44c8 | |||
ad795caed5 |
@ -219,7 +219,7 @@ def load_fcurve(fcurve_data, fcurve):
|
||||
def dump_animation_data(datablock):
|
||||
animation_data = {}
|
||||
if has_action(datablock):
|
||||
animation_data['action'] = datablock.animation_data.action.name
|
||||
animation_data['action'] = datablock.animation_data.action.uuid
|
||||
if has_driver(datablock):
|
||||
animation_data['drivers'] = []
|
||||
for driver in datablock.animation_data.drivers:
|
||||
@ -241,8 +241,10 @@ def load_animation_data(animation_data, datablock):
|
||||
for driver in animation_data['drivers']:
|
||||
load_driver(datablock, driver)
|
||||
|
||||
if 'action' in animation_data:
|
||||
datablock.animation_data.action = bpy.data.actions[animation_data['action']]
|
||||
action = animation_data.get('action')
|
||||
if action:
|
||||
action = resolve_datablock_from_uuid(action, bpy.data.actions)
|
||||
datablock.animation_data.action = action
|
||||
elif datablock.animation_data.action:
|
||||
datablock.animation_data.action = None
|
||||
|
||||
|
@ -404,6 +404,7 @@ class BlMaterial(ReplicatedDatablock):
|
||||
bl_check_common = False
|
||||
bl_icon = 'MATERIAL_DATA'
|
||||
bl_reload_parent = False
|
||||
bl_reload_child = True
|
||||
|
||||
@staticmethod
|
||||
def construct(data: dict) -> object:
|
||||
@ -411,8 +412,6 @@ class BlMaterial(ReplicatedDatablock):
|
||||
|
||||
@staticmethod
|
||||
def load(data: dict, datablock: object):
|
||||
load_animation_data(data.get('animation_data'), datablock)
|
||||
|
||||
loader = Loader()
|
||||
|
||||
is_grease_pencil = data.get('is_grease_pencil')
|
||||
@ -429,6 +428,8 @@ class BlMaterial(ReplicatedDatablock):
|
||||
datablock.use_nodes = True
|
||||
|
||||
load_node_tree(data['node_tree'], datablock.node_tree)
|
||||
load_animation_data(data.get('nodes_animation_data'), datablock.node_tree)
|
||||
load_animation_data(data.get('animation_data'), datablock)
|
||||
|
||||
@staticmethod
|
||||
def dump(datablock: object) -> dict:
|
||||
@ -496,8 +497,10 @@ class BlMaterial(ReplicatedDatablock):
|
||||
data['grease_pencil'] = gp_mat_dumper.dump(datablock.grease_pencil)
|
||||
elif datablock.use_nodes:
|
||||
data['node_tree'] = dump_node_tree(datablock.node_tree)
|
||||
data['nodes_animation_data'] = dump_animation_data(datablock.node_tree)
|
||||
|
||||
data['animation_data'] = dump_animation_data(datablock)
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
@ -511,7 +514,7 @@ class BlMaterial(ReplicatedDatablock):
|
||||
|
||||
if datablock.use_nodes:
|
||||
deps.extend(get_node_tree_dependencies(datablock.node_tree))
|
||||
|
||||
deps.extend(resolve_animation_dependencies(datablock.node_tree))
|
||||
deps.extend(resolve_animation_dependencies(datablock))
|
||||
|
||||
return deps
|
||||
|
Submodule multi_user/libs/replication updated: cb4cdd0444...ce3a7b4363
@ -100,7 +100,7 @@ def initialize_session():
|
||||
|
||||
# Step 2: Load nodes
|
||||
logging.info("Applying nodes")
|
||||
for node in session.repository.index_sorted:
|
||||
for node in session.repository.heads:
|
||||
porcelain.apply(session.repository, node)
|
||||
|
||||
logging.info("Registering timers")
|
||||
@ -604,9 +604,9 @@ class SessionApply(bpy.types.Operator):
|
||||
node_ref = session.repository.graph.get(self.target)
|
||||
porcelain.apply(session.repository,
|
||||
self.target,
|
||||
force=True,
|
||||
force_dependencies=self.reset_dependencies)
|
||||
force=True)
|
||||
impl = session.repository.rdp.get_implementation(node_ref.instance)
|
||||
# NOTE: find another way to handle child and parent automatic reloading
|
||||
if impl.bl_reload_parent:
|
||||
for parent in session.repository.graph.get_parents(self.target):
|
||||
logging.debug(f"Refresh parent {parent}")
|
||||
@ -614,6 +614,11 @@ class SessionApply(bpy.types.Operator):
|
||||
porcelain.apply(session.repository,
|
||||
parent.uuid,
|
||||
force=True)
|
||||
if hasattr(impl, 'bl_reload_child') and impl.bl_reload_child:
|
||||
for dep in node_ref.dependencies:
|
||||
porcelain.apply(session.repository,
|
||||
dep,
|
||||
force=True)
|
||||
except Exception as e:
|
||||
self.report({'ERROR'}, repr(e))
|
||||
traceback.print_exc()
|
||||
@ -637,7 +642,7 @@ class SessionCommit(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
try:
|
||||
porcelain.commit(session.repository, self.target)
|
||||
porcelain.push(session.repository, 'origin', self.target)
|
||||
porcelain.push(session.repository, 'origin', self.target, force=True)
|
||||
return {"FINISHED"}
|
||||
except Exception as e:
|
||||
self.report({'ERROR'}, repr(e))
|
||||
|
@ -94,15 +94,35 @@ def project_to_viewport(region: bpy.types.Region, rv3d: bpy.types.RegionView3D,
|
||||
return [target.x, target.y, target.z]
|
||||
|
||||
|
||||
def bbox_from_obj(obj: bpy.types.Object, radius: float) -> list:
|
||||
def bbox_from_obj(obj: bpy.types.Object) -> list:
|
||||
""" Generate a bounding box for a given object by using its world matrix
|
||||
|
||||
:param obj: target object
|
||||
:type obj: bpy.types.Object
|
||||
:param radius: bounding box radius
|
||||
:type radius: float
|
||||
:return: list of 8 points [(x,y,z),...]
|
||||
:return: list of 8 points [(x,y,z),...], list of 12 link between these points [(1,2),...]
|
||||
"""
|
||||
radius = 1.0 # Radius of the bounding box
|
||||
vertex_indices = (
|
||||
(0, 1), (0, 2), (1, 3), (2, 3),
|
||||
(4, 5), (4, 6), (5, 7), (6, 7),
|
||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||
|
||||
if obj.type == 'EMPTY':
|
||||
radius = obj.empty_display_size
|
||||
elif obj.type == 'LIGHT':
|
||||
radius = obj.data.shadow_soft_size
|
||||
elif obj.type == 'LIGHT_PROBE':
|
||||
radius = obj.data.influence_distance
|
||||
elif obj.type == 'CAMERA':
|
||||
radius = obj.data.display_size
|
||||
elif hasattr(obj, 'bound_box'):
|
||||
vertex_indices = (
|
||||
(0, 1), (1, 2), (2, 3), (0, 3),
|
||||
(4, 5), (5, 6), (6, 7), (4, 7),
|
||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||
vertex_pos = get_bb_coords_from_obj(obj)
|
||||
return vertex_pos, vertex_indices
|
||||
|
||||
coords = [
|
||||
(-radius, -radius, -radius), (+radius, -radius, -radius),
|
||||
(-radius, +radius, -radius), (+radius, +radius, -radius),
|
||||
@ -112,9 +132,37 @@ def bbox_from_obj(obj: bpy.types.Object, radius: float) -> list:
|
||||
base = obj.matrix_world
|
||||
bbox_corners = [base @ mathutils.Vector(corner) for corner in coords]
|
||||
|
||||
return [(point.x, point.y, point.z)
|
||||
for point in bbox_corners]
|
||||
vertex_pos = [(point.x, point.y, point.z) for point in bbox_corners]
|
||||
|
||||
return vertex_pos, vertex_indices
|
||||
|
||||
def bbox_from_instance_collection(ic: bpy.types.Object) -> list:
|
||||
""" Generate a bounding box for a given instance collection by using its objects
|
||||
|
||||
:param ic: target instance collection
|
||||
:type ic: bpy.types.Object
|
||||
:param radius: bounding box radius
|
||||
:type radius: float
|
||||
:return: list of 8*objs points [(x,y,z),...], tuple of 12*objs link between these points [(1,2),...]
|
||||
"""
|
||||
vertex_pos = []
|
||||
vertex_indices = ()
|
||||
|
||||
for obj_index, obj in enumerate(ic.instance_collection.objects):
|
||||
vertex_pos_temp, vertex_indices_temp = bbox_from_obj(obj)
|
||||
vertex_pos += vertex_pos_temp
|
||||
vertex_indices_list_temp = list(list(indice) for indice in vertex_indices_temp)
|
||||
for indice in vertex_indices_list_temp:
|
||||
indice[0] += 8*obj_index
|
||||
indice[1] += 8*obj_index
|
||||
vertex_indices_temp = tuple(tuple(indice) for indice in vertex_indices_list_temp)
|
||||
vertex_indices += vertex_indices_temp
|
||||
|
||||
bbox_corners = [ic.matrix_world @ mathutils.Vector(vertex) for vertex in vertex_pos]
|
||||
|
||||
vertex_pos = [(point.x, point.y, point.z) for point in bbox_corners]
|
||||
|
||||
return vertex_pos, vertex_indices
|
||||
|
||||
def generate_user_camera() -> list:
|
||||
""" Generate a basic camera represention of the user point of view
|
||||
@ -296,36 +344,14 @@ class UserSelectionWidget(Widget):
|
||||
|
||||
def draw(self):
|
||||
user_selection = self.data.get('selected_objects')
|
||||
for select_ob in user_selection:
|
||||
ob = find_from_attr("uuid", select_ob, bpy.data.objects)
|
||||
if not ob:
|
||||
for select_obj in user_selection:
|
||||
obj = find_from_attr("uuid", select_obj, bpy.data.objects)
|
||||
if not obj:
|
||||
return
|
||||
|
||||
vertex_pos = bbox_from_obj(ob, 1.0)
|
||||
vertex_indices = (
|
||||
(0, 1), (1, 2), (2, 3), (0, 3),
|
||||
(4, 5), (5, 6), (6, 7), (4, 7),
|
||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||
|
||||
if ob.instance_collection:
|
||||
for obj in ob.instance_collection.objects:
|
||||
if obj.type == 'MESH' and hasattr(obj, 'bound_box'):
|
||||
vertex_pos = get_bb_coords_from_obj(obj, instance=ob)
|
||||
break
|
||||
elif ob.type == 'EMPTY':
|
||||
vertex_pos = bbox_from_obj(ob, ob.empty_display_size)
|
||||
elif ob.type == 'LIGHT':
|
||||
vertex_pos = bbox_from_obj(ob, ob.data.shadow_soft_size)
|
||||
elif ob.type == 'LIGHT_PROBE':
|
||||
vertex_pos = bbox_from_obj(ob, ob.data.influence_distance)
|
||||
elif ob.type == 'CAMERA':
|
||||
vertex_pos = bbox_from_obj(ob, ob.data.display_size)
|
||||
elif hasattr(ob, 'bound_box'):
|
||||
vertex_indices = (
|
||||
(0, 1), (1, 2), (2, 3), (0, 3),
|
||||
(4, 5), (5, 6), (6, 7), (4, 7),
|
||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||
vertex_pos = get_bb_coords_from_obj(ob)
|
||||
if obj.instance_collection:
|
||||
vertex_pos, vertex_indices = bbox_from_instance_collection(obj)
|
||||
else :
|
||||
vertex_pos, vertex_indices = bbox_from_obj(obj)
|
||||
|
||||
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
||||
batch = batch_for_shader(
|
||||
@ -338,7 +364,6 @@ class UserSelectionWidget(Widget):
|
||||
shader.uniform_float("color", self.data.get('color'))
|
||||
batch.draw(shader)
|
||||
|
||||
|
||||
class UserNameWidget(Widget):
|
||||
draw_type = 'POST_PIXEL'
|
||||
|
||||
|
@ -129,6 +129,11 @@ class ApplyTimer(Timer):
|
||||
porcelain.apply(session.repository,
|
||||
parent.uuid,
|
||||
force=True)
|
||||
if hasattr(impl, 'bl_reload_child') and impl.bl_reload_child:
|
||||
for dep in node_ref.dependencies:
|
||||
porcelain.apply(session.repository,
|
||||
dep,
|
||||
force=True)
|
||||
|
||||
|
||||
class DynamicRightSelectTimer(Timer):
|
||||
|
@ -555,20 +555,15 @@ class SESSION_PT_repository(bpy.types.Panel):
|
||||
# Properties
|
||||
owned_nodes = [k for k, v in session.repository.graph.items() if v.owner==settings.username]
|
||||
|
||||
filtered_node = owned_nodes if runtime_settings.filter_owned else session.repository.graph.keys()
|
||||
filtered_node = owned_nodes if runtime_settings.filter_owned else list(session.repository.graph.keys())
|
||||
|
||||
if runtime_settings.filter_name:
|
||||
for node_id in filtered_node:
|
||||
node_instance = session.repository.graph.get(node_id)
|
||||
name = node_instance.data.get('name')
|
||||
if runtime_settings.filter_name not in name:
|
||||
filtered_node.remove(node_id)
|
||||
filtered_node = [n for n in filtered_node if runtime_settings.filter_name.lower() in session.repository.graph.get(n).data.get('name').lower()]
|
||||
|
||||
if filtered_node:
|
||||
col = layout.column(align=True)
|
||||
for key in filtered_node:
|
||||
draw_property(context, col, key)
|
||||
|
||||
else:
|
||||
layout.row().label(text="Empty")
|
||||
|
||||
|
Reference in New Issue
Block a user