Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'depsgraph_debug.py')
-rw-r--r--depsgraph_debug.py197
1 files changed, 197 insertions, 0 deletions
diff --git a/depsgraph_debug.py b/depsgraph_debug.py
new file mode 100644
index 00000000..9d919dcc
--- /dev/null
+++ b/depsgraph_debug.py
@@ -0,0 +1,197 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import bpy
+from bpy.types import (
+ Operator,
+ Panel,
+ )
+from bpy.props import (StringProperty, )
+
+bl_info = {
+ "name": "Dependency Graph Debug",
+ "author": "Sergey Sharybin",
+ "version": (0, 1),
+ "blender": (2, 79, 0),
+ "description": "Various dependency graph debugging tools",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Development"}
+
+
+def _get_depsgraph(context):
+ scene = context.scene
+ if bpy.app.version < (2, 80, 0,):
+ return scene.depsgraph
+ else:
+ scene_layer = scene.render_layers.active
+ return scene_layer.depsgraph
+
+
+class SCENE_OT_depsgraph_graphviz(Operator):
+ bl_idname = "scene.depsgraph_graphviz"
+ bl_label = "Save Depsgraph"
+ bl_description = "Save current scene's dependency graph to a graphviz file"
+
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath used for saving the file",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
+
+ @classmethod
+ def poll(cls, context):
+ depsgraph = _get_depsgraph(context)
+ return depsgraph is not None
+
+ def invoke(self, context, event):
+ import os
+ if not self.filepath:
+ blend_filepath = context.blend_data.filepath
+ if not blend_filepath:
+ blend_filepath = "deg"
+ else:
+ blend_filepath = os.path.splitext(blend_filepath)[0]
+
+ self.filepath = blend_filepath + ".dot"
+
+ context.window_manager.fileselect_add(self)
+
+ return {'RUNNING_MODAL'}
+
+ def execute(self, context):
+ depsgraph = _get_depsgraph(context)
+ depsgraph.debug_graphviz(self.filepath)
+ return {'FINISHED'}
+
+
+class SCENE_OT_depsgraph_image(Operator):
+ bl_idname = "scene.depsgraph_image"
+ bl_label = "Depsgraph as Image"
+ bl_description = "Create new image datablock from the dependency graph"
+
+ def _getOrCreateImageForAbsPath(self, filepath):
+ for image in bpy.data.images:
+ if image.filepath == filepath:
+ image.reload()
+ return image
+ return bpy.data.images.load(filepath, check_existing=True)
+
+ def _findBestImageEditor(self, context, image):
+ first_none_editor = None
+ for area in context.screen.areas:
+ if area.type != 'IMAGE_EDITOR':
+ continue
+ for space in area.spaces:
+ if space.type != 'IMAGE_EDITOR':
+ continue
+ if not space.image:
+ first_none_editor = space
+ else:
+ if space.image == image:
+ return space
+ return first_none_editor
+
+ def execute(self, context):
+ import os
+ import subprocess
+ import tempfile
+ # Create temporary file.
+ fd, dot_filepath = tempfile.mkstemp(suffix=".dot")
+ os.close(fd)
+ # Save dependency graph to graphviz file.
+ depsgraph = _get_depsgraph(context)
+ depsgraph.debug_graphviz(dot_filepath)
+ # Convert graphviz to PNG image.
+ png_filepath = os.path.join(bpy.app.tempdir, "depsgraph.png")
+ command = ("dot", "-Tpng", dot_filepath, "-o", png_filepath)
+ image = None
+ try:
+ subprocess.run(command)
+ # Open image in Blender.
+ image = self._getOrCreateImageForAbsPath(png_filepath)
+ except:
+ self.report({'ERROR'}, "Error invoking dot command")
+ return {'CANCELLED'}
+ finally:
+ # Remove graphviz file.
+ os.remove(dot_filepath)
+ editor = self._findBestImageEditor(context, image)
+ if editor:
+ editor.image = image
+ return {'FINISHED'}
+
+
+class SCENE_PT_depsgraph(bpy.types.Panel):
+ bl_label = "Dependency Graph"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "scene"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ if bpy.app.version >= (2, 80, 0,):
+ return False
+ depsgraph = _get_depsgraph(context)
+ return depsgraph is not None
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("scene.depsgraph_graphviz")
+ layout.operator("scene.depsgraph_image")
+
+
+class RENDERLAYER_PT_depsgraph(bpy.types.Panel):
+ bl_label = "Dependency Graph"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "render_layer"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ if bpy.app.version < (2, 80, 0,):
+ return False
+ depsgraph = _get_depsgraph(context)
+ return depsgraph is not None
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("scene.depsgraph_graphviz")
+ layout.operator("scene.depsgraph_image")
+
+
+def register():
+ bpy.utils.register_class(SCENE_OT_depsgraph_graphviz)
+ bpy.utils.register_class(SCENE_OT_depsgraph_image)
+ bpy.utils.register_class(SCENE_PT_depsgraph)
+ bpy.utils.register_class(RENDERLAYER_PT_depsgraph)
+
+
+def unregister():
+ bpy.utils.unregister_class(SCENE_OT_depsgraph_graphviz)
+ bpy.utils.unregister_class(SCENE_OT_depsgraph_image)
+ bpy.utils.unregister_class(SCENE_PT_depsgraph)
+ bpy.utils.unregister_class(RENDERLAYER_PT_depsgraph)
+
+
+if __name__ == "__main__":
+ register()