2017-02-09 22:52:47 +01:00
|
|
|
import os
|
|
|
|
import sys
|
2018-05-24 22:16:28 +02:00
|
|
|
import bpy
|
2016-10-31 19:29:03 +01:00
|
|
|
from bpy.app.handlers import persistent
|
2017-03-15 12:30:14 +01:00
|
|
|
import arm.utils
|
|
|
|
import arm.props as props
|
|
|
|
import arm.make as make
|
|
|
|
import arm.make_state as state
|
2018-08-08 10:29:07 +02:00
|
|
|
import arm.api
|
2016-10-19 13:28:06 +02:00
|
|
|
|
|
|
|
last_operator = None
|
2017-04-01 21:25:57 +02:00
|
|
|
first_update = True
|
2018-05-24 22:16:28 +02:00
|
|
|
v8_started = False
|
2016-10-19 13:28:06 +02:00
|
|
|
|
2016-10-31 19:29:03 +01:00
|
|
|
@persistent
|
2018-05-24 22:16:28 +02:00
|
|
|
def on_scene_update_pre(context):
|
|
|
|
# TODO: get rid of this function as soon as there is a proper way to detect object data updates
|
2016-10-19 13:28:06 +02:00
|
|
|
global last_operator
|
2017-04-01 21:25:57 +02:00
|
|
|
global first_update
|
2018-05-24 22:16:28 +02:00
|
|
|
global v8_started
|
2017-04-01 21:25:57 +02:00
|
|
|
|
|
|
|
if first_update == True: # Skip first one, object reports is_update_data
|
|
|
|
first_update = False
|
|
|
|
return
|
2016-10-19 13:28:06 +02:00
|
|
|
|
2018-06-19 23:21:53 +02:00
|
|
|
# Viewport player
|
2018-05-24 22:16:28 +02:00
|
|
|
with_armory = bpy.context.scene.render.engine == 'ARMORY'
|
|
|
|
if with_armory:
|
|
|
|
play_area = None
|
|
|
|
if bpy.context.screen != None:
|
|
|
|
for area in bpy.context.screen.areas:
|
|
|
|
if area.type == 'VIEW_3D':
|
|
|
|
play_area = area
|
|
|
|
break
|
|
|
|
if play_area != None and play_area.spaces[0].shading.type == 'MATERIAL':
|
|
|
|
if not v8_started:
|
|
|
|
v8_started = True
|
|
|
|
make.build_viewport()
|
|
|
|
else:
|
|
|
|
v8_started = False
|
|
|
|
|
2018-06-19 23:21:53 +02:00
|
|
|
if state.redraw_ui and bpy.context.screen != None:
|
|
|
|
for area in bpy.context.screen.areas:
|
|
|
|
if area.type == 'VIEW_3D' or area.type == 'PROPERTIES':
|
|
|
|
area.tag_redraw()
|
|
|
|
state.redraw_ui = False
|
|
|
|
|
2018-05-24 22:16:28 +02:00
|
|
|
# Recache edited data
|
2016-11-07 00:31:48 +01:00
|
|
|
ops = bpy.context.window_manager.operators
|
|
|
|
operators_changed = False
|
|
|
|
if len(ops) > 0 and last_operator != ops[-1]:
|
|
|
|
last_operator = ops[-1]
|
|
|
|
operators_changed = True
|
2018-05-22 19:44:54 +02:00
|
|
|
|
2017-04-01 21:25:57 +02:00
|
|
|
if hasattr(bpy.context, 'active_object'):
|
|
|
|
obj = bpy.context.active_object
|
|
|
|
if obj != None:
|
2017-11-03 01:22:07 +01:00
|
|
|
if obj.data != None and obj.data.is_updated:
|
2017-04-01 21:25:57 +02:00
|
|
|
recache(obj)
|
2017-11-03 01:22:07 +01:00
|
|
|
if len(ops) > 0 and ops[-1].bl_idname == 'OBJECT_OT_transform_apply':
|
|
|
|
recache(obj)
|
2018-05-24 22:16:28 +02:00
|
|
|
# New children
|
2017-11-03 01:22:07 +01:00
|
|
|
if obj.type == 'ARMATURE':
|
2017-04-01 21:25:57 +02:00
|
|
|
for c in obj.children:
|
2017-11-03 01:22:07 +01:00
|
|
|
if c.data != None and c.data.is_updated:
|
2017-04-01 21:25:57 +02:00
|
|
|
recache(c)
|
|
|
|
if hasattr(bpy.context, 'sculpt_object') and bpy.context.sculpt_object != None:
|
|
|
|
recache(bpy.context.sculpt_object)
|
|
|
|
if hasattr(bpy.context, 'active_pose_bone') and bpy.context.active_pose_bone != None:
|
|
|
|
recache(bpy.context.active_object)
|
2016-10-19 13:28:06 +02:00
|
|
|
|
2017-01-03 00:16:54 +01:00
|
|
|
if hasattr(bpy.context, 'object'):
|
|
|
|
obj = bpy.context.object
|
|
|
|
if obj != None:
|
|
|
|
if operators_changed:
|
2017-02-15 16:55:46 +01:00
|
|
|
op_changed(ops[-1], obj)
|
2017-01-03 00:16:54 +01:00
|
|
|
if obj.active_material != None and obj.active_material.is_updated:
|
2018-05-24 22:16:28 +02:00
|
|
|
if obj.active_material.lock_cache == True: # is_cached was set to true, resulting in a is_updated call
|
2017-01-18 14:52:51 +01:00
|
|
|
obj.active_material.lock_cache = False
|
|
|
|
else:
|
|
|
|
obj.active_material.is_cached = False
|
2016-11-07 00:31:48 +01:00
|
|
|
|
2017-07-03 15:16:15 +02:00
|
|
|
# Invalidate logic node tree cache if it is being edited..
|
|
|
|
space = arm.utils.logic_editor_space()
|
|
|
|
if space != None:
|
|
|
|
space.node_tree.is_cached = False
|
2017-05-25 16:48:41 +02:00
|
|
|
|
2017-11-03 01:22:07 +01:00
|
|
|
def recache(obj):
|
|
|
|
# Moving keyframes triggers is_updated_data..
|
2018-06-19 23:21:53 +02:00
|
|
|
if state.proc_build != None:
|
2017-11-03 01:22:07 +01:00
|
|
|
return
|
|
|
|
if obj.data == None:
|
|
|
|
return
|
|
|
|
if hasattr(obj.data, 'arm_cached'):
|
|
|
|
obj.data.arm_cached = False
|
2017-04-01 21:25:57 +02:00
|
|
|
|
2017-02-15 16:55:46 +01:00
|
|
|
def op_changed(op, obj):
|
|
|
|
# Recache mesh data
|
|
|
|
if op.bl_idname == 'OBJECT_OT_modifier_add' or \
|
|
|
|
op.bl_idname == 'OBJECT_OT_modifier_remove' or \
|
|
|
|
op.bl_idname == 'OBJECT_OT_transform_apply' or \
|
2017-11-11 23:25:58 +01:00
|
|
|
op.bl_idname == 'APPLY_OT_transformlocrotscale' or \
|
2017-02-15 16:55:46 +01:00
|
|
|
op.bl_idname == 'OBJECT_OT_shade_smooth' or \
|
|
|
|
op.bl_idname == 'OBJECT_OT_shade_flat':
|
2017-11-03 01:22:07 +01:00
|
|
|
# Note: Blender reverts object data when manipulating
|
2017-11-20 13:38:19 +01:00
|
|
|
# OBJECT_OT_transform_apply operator.. recaching object flag instead
|
2017-11-03 01:22:07 +01:00
|
|
|
obj.arm_cached = False
|
2017-11-11 19:03:10 +01:00
|
|
|
if op.bl_idname.startswith('MARKER_OT_'):
|
|
|
|
# Marker changed, recache action
|
|
|
|
obj.data.arm_cached = False
|
2017-02-09 22:52:47 +01:00
|
|
|
|
2017-03-06 02:29:03 +01:00
|
|
|
appended_py_paths = []
|
2016-10-31 19:29:03 +01:00
|
|
|
@persistent
|
|
|
|
def on_load_post(context):
|
2017-03-06 02:29:03 +01:00
|
|
|
global appended_py_paths
|
2017-04-01 21:25:57 +02:00
|
|
|
global first_update
|
|
|
|
|
|
|
|
first_update = True
|
2017-02-09 22:52:47 +01:00
|
|
|
|
2016-10-31 19:29:03 +01:00
|
|
|
props.init_properties_on_load()
|
2017-11-22 21:17:36 +01:00
|
|
|
reload_blend_data()
|
2016-10-31 19:29:03 +01:00
|
|
|
|
2017-10-17 13:39:50 +02:00
|
|
|
bpy.ops.arm.sync_proxy()
|
|
|
|
|
2017-03-06 02:29:03 +01:00
|
|
|
wrd = bpy.data.worlds['Arm']
|
2017-05-24 23:04:24 +02:00
|
|
|
wrd.arm_recompile = True
|
2018-08-08 10:29:07 +02:00
|
|
|
arm.api.drivers = dict()
|
2017-05-24 23:04:24 +02:00
|
|
|
|
2018-08-08 10:29:07 +02:00
|
|
|
# Load libraries
|
2017-09-05 00:36:16 +02:00
|
|
|
if os.path.exists(arm.utils.get_fp() + '/Libraries'):
|
|
|
|
libs = os.listdir(arm.utils.get_fp() + '/Libraries')
|
|
|
|
for lib in libs:
|
|
|
|
if os.path.isdir(arm.utils.get_fp() + '/Libraries/' + lib):
|
|
|
|
fp = arm.utils.get_fp() + '/Libraries/' + lib
|
|
|
|
if fp not in appended_py_paths and os.path.exists(fp + '/blender.py'):
|
|
|
|
sys.path.append(fp)
|
|
|
|
appended_py_paths.append(fp)
|
|
|
|
import blender
|
|
|
|
blender.register()
|
2017-02-09 22:52:47 +01:00
|
|
|
|
2017-12-11 00:55:26 +01:00
|
|
|
arm.utils.update_trait_groups()
|
|
|
|
|
2017-11-22 21:17:36 +01:00
|
|
|
def reload_blend_data():
|
|
|
|
armory_pbr = bpy.data.node_groups.get('Armory PBR')
|
|
|
|
if armory_pbr == None:
|
|
|
|
load_library('Armory PBR')
|
|
|
|
|
|
|
|
def load_library(asset_name):
|
|
|
|
if bpy.data.filepath.endswith('arm_data.blend'): # Prevent load in library itself
|
|
|
|
return
|
|
|
|
sdk_path = arm.utils.get_sdk_path()
|
|
|
|
data_path = sdk_path + '/armory/blender/data/arm_data.blend'
|
|
|
|
data_names = [asset_name]
|
|
|
|
|
|
|
|
# Import
|
|
|
|
data_refs = data_names.copy()
|
|
|
|
with bpy.data.libraries.load(data_path, link=False) as (data_from, data_to):
|
|
|
|
data_to.node_groups = data_refs
|
|
|
|
|
|
|
|
for ref in data_refs:
|
|
|
|
ref.use_fake_user = True
|
|
|
|
|
2016-10-19 13:28:06 +02:00
|
|
|
def register():
|
2018-05-24 22:16:28 +02:00
|
|
|
if hasattr(bpy.app.handlers, 'scene_update_pre'):
|
|
|
|
bpy.app.handlers.scene_update_pre.append(on_scene_update_pre)
|
2016-10-31 19:29:03 +01:00
|
|
|
bpy.app.handlers.load_post.append(on_load_post)
|
2018-08-20 16:26:52 +02:00
|
|
|
# TODO: On windows, on_load_post is not called when opening .blend file from explorer
|
|
|
|
if arm.utils.get_os() == 'win' and arm.utils.get_fp() != '':
|
|
|
|
on_load_post(None)
|
2017-11-22 21:17:36 +01:00
|
|
|
reload_blend_data()
|
2016-10-19 13:28:06 +02:00
|
|
|
|
|
|
|
def unregister():
|
2018-05-24 22:16:28 +02:00
|
|
|
if hasattr(bpy.app.handlers, 'scene_update_pre'):
|
|
|
|
bpy.app.handlers.scene_update_pre.remove(on_scene_update_pre)
|
2017-01-13 15:11:30 +01:00
|
|
|
bpy.app.handlers.load_post.remove(on_load_post)
|