[Bf-blender-cvs] [9fe7c33] depsgraph_refactor: Depsgraph WIP: Basic support for OGDF export

Joshua Leung noreply at git.blender.org
Thu Jan 29 14:13:01 CET 2015


Commit: 9fe7c3374219af6a6da6dcfe568da26e4f0351b8
Author: Joshua Leung
Date:   Fri Jan 30 01:28:53 2015 +1300
Branches: depsgraph_refactor
https://developer.blender.org/rB9fe7c3374219af6a6da6dcfe568da26e4f0351b8

Depsgraph WIP: Basic support for OGDF export

This introduces initial preliminary support for OGDF export, including the
code to populate the graph, and all the supporting operator/rna stuff.
Much of this has been copied + adapted from the code for the GraphViz
exporting, though we are likely to need to adapt this later on.

* Currently, there is no layout engine used, so the exported graph won't look
  like anything exists. But, at least all the data does get exported.

* Debugging Note: Crashes related to the ogdf string class when assigning to attributes
  occur if you don't set the GraphAttributes flag corresponding to that attribute.

===================================================================

M	release/scripts/startup/bl_operators/anim.py
M	release/scripts/startup/bl_ui/space_info.py
M	source/blender/depsgraph/DEG_depsgraph_debug.h
M	source/blender/depsgraph/intern/depsgraph_debug_ogdf.cpp
M	source/blender/makesrna/intern/rna_depsgraph.c

===================================================================

diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index b563e7f..10a9c02 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -393,9 +393,43 @@ class DEPSGRAPH_OT_rebuild(Operator):
         context.scene.depsgraph.debug_rebuild()
         return {'FINISHED'}
 
+
+class DEPSGRAPH_OT_export_gml(Operator):
+    """Export the dependency graph to GML using OGDF"""
+    bl_idname = "depsgraph.export_gml"
+    bl_label = "Export Depsgraph to GML"
+    bl_options = {'REGISTER'}
+    
+    filepath = StringProperty(
+            subtype='FILE_PATH',
+            #value=bpy.path.abspath("../graphs/"),
+            )
+    filter_folder = BoolProperty(
+            name="Filter folders",
+            default=True,
+            options={'HIDDEN'},
+            )
+    filter_glob = StringProperty(
+            name="Extension Filter",
+            default="*.gml",
+            options={'HIDDEN'},
+            )
+
+    def execute(self, context):
+        if not self.filepath:
+            raise Exception("Filepath not set")
+            
+        context.scene.depsgraph.debug_ogdf(self.filepath)
+        return {'FINISHED'}
         
+    def invoke(self, context, event):
+        wm = context.window_manager
+        wm.fileselect_add(self)
+        return {'RUNNING_MODAL'}
+
+
 class DEPSGRAPH_OT_export_graphviz(Operator):
-    """Force the dependency graph to be rebuilt to account for modified dependencies"""
+    """Export the dependency graph for rendering using GraphViz"""
     bl_idname = "depsgraph.export_graphviz"
     bl_label = "Export Depsgraph to Graphviz"
     bl_options = {'REGISTER'}
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 2d120b4..5c5330a 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -54,7 +54,8 @@ class INFO_HT_header(Header):
         row.label(text="Depsgraph:", icon='RADIO')
         row.operator("depsgraph.stats", text="", icon='INFO')
         row.operator("depsgraph.rebuild", text="", icon='FILE_REFRESH')
-        row.operator("depsgraph.export_graphviz", text="Export...", icon='EXPORT').filepath = "graph.dot"
+        row.operator("depsgraph.export_graphviz", text="To GV...", icon='EXPORT').filepath = "graph.dot"
+        row.operator("depsgraph.export_gml", text="GML...", icon='EXPORT').filepath = "graph.gml"
 
         layout.separator()
 
diff --git a/source/blender/depsgraph/DEG_depsgraph_debug.h b/source/blender/depsgraph/DEG_depsgraph_debug.h
index 53dd205..607dbce 100644
--- a/source/blender/depsgraph/DEG_depsgraph_debug.h
+++ b/source/blender/depsgraph/DEG_depsgraph_debug.h
@@ -84,9 +84,10 @@ void DEG_stats_simple(const struct Depsgraph *graph,
                       size_t *r_relations);
 
 /* ************************************************ */
-/* Graphviz Debugging */
+/* Diagram-Based Graph Debugging */
 
 void DEG_debug_graphviz(const struct Depsgraph *graph, FILE *stream, const char *label, bool show_eval);
+void DEG_debug_ogdf(const struct Depsgraph *graph, const char *filename);
 
 /* ************************************************ */
 
diff --git a/source/blender/depsgraph/intern/depsgraph_debug_ogdf.cpp b/source/blender/depsgraph/intern/depsgraph_debug_ogdf.cpp
index 66040f4..8317ba9 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug_ogdf.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_debug_ogdf.cpp
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+/* NOTE: OGDF needs to come before Blender headers, or else there will be compile errors on mingw64 */
 #include <ogdf/basic/Graph.h>
 #include <ogdf/layered/OptimalHierarchyLayout.h>
 
@@ -54,16 +55,22 @@ extern "C" {
 #include "depsgraph_types.h"
 #include "depsgraph_intern.h"
 
-using namespace ogdf;
-
 /* ****************** */
 /* OGDF Debugging */
 
+/* Typedef for mapping from Depsgraph Nodes to OGDF Nodes */
+typedef unordered_map<const DepsNode *, ogdf::node> GraphNodesMap;
+
+/* Helper data passed to all calls here */
 struct DebugContext {
-	FILE *file;
+	/* the output graph, and formatting info for the graph */
+	ogdf::Graph *G;
+	ogdf::GraphAttributes *GA;
 
-	Graph *outgraph;
+	/* mapping from Depsgraph Nodes to OGDF nodes */
+	GraphNodesMap node_map;
 
+	/* flags for what to include */
 	bool show_tags;
 	bool show_eval_priority;
 
@@ -76,44 +83,125 @@ static void deg_debug_ogdf_graph_relations(const DebugContext &ctx, const Depsgr
 
 /* -------------------------------- */
 
+/* Only one should be enabled, defines whether graphviz nodes
+* get colored by individual types or classes.
+*/
+#define COLOR_SCHEME_NODE_CLASS 1
+//#define COLOR_SCHEME_NODE_TYPE  2
+
+#ifdef COLOR_SCHEME_NODE_TYPE
+static const int deg_debug_node_type_color_map[][2] = {
+	{ DEPSNODE_TYPE_ROOT, 0 },
+	{ DEPSNODE_TYPE_TIMESOURCE, 1 },
+	{ DEPSNODE_TYPE_ID_REF, 2 },
+	{ DEPSNODE_TYPE_SUBGRAPH, 3 },
+
+	/* Outer Types */
+	{ DEPSNODE_TYPE_PARAMETERS, 4 },
+	{ DEPSNODE_TYPE_PROXY, 5 },
+	{ DEPSNODE_TYPE_ANIMATION, 6 },
+	{ DEPSNODE_TYPE_TRANSFORM, 7 },
+	{ DEPSNODE_TYPE_GEOMETRY, 8 },
+	{ DEPSNODE_TYPE_SEQUENCER, 9 },
+	{ DEPSNODE_TYPE_SHADING, 10 },
+	{ -1, 0 }
+};
+#endif
+
+static const int deg_debug_max_colors = 12;
+static const char *deg_debug_colors_dark[] = {"#6e8997", "#144f77", "#76945b",
+                                              "#216a1d", "#a76665", "#971112",
+                                              "#a87f49", "#0a9540", "#86768e",
+                                              "#462866", "#a9a965", "#753b1a"};
+static const char *deg_debug_colors[] = {"#a6cee3", "#1f78b4", "#b2df8a",
+                                         "#33a02c", "#fb9a99", "#e31a1c",
+                                         "#fdbf6f", "#ff7f00", "#cab2d6",
+                                         "#6a3d9a", "#ffff99", "#b15928"};
+static const char *deg_debug_colors_light[] = {"#8dd3c7", "#ffffb3", "#bebada",
+                                               "#fb8072", "#80b1d3", "#fdb462",
+                                               "#b3de69", "#fccde5", "#d9d9d9",
+                                               "#bc80bd", "#ccebc5","#ffed6f"};
+
+static int deg_debug_node_color_index(const DepsNode *node)
+{
+#ifdef COLOR_SCHEME_NODE_CLASS
+	/* Some special types. */
+	switch (node->type) {
+		case DEPSNODE_TYPE_ID_REF:
+			return 5;
+		case DEPSNODE_TYPE_OPERATION:
+		{
+			OperationDepsNode *op_node = (OperationDepsNode *)node;
+			if (op_node->is_noop())
+				return 8;
+		}
+
+		default:
+			break;
+	}
+	/* Do others based on class. */
+	switch (node->tclass) {
+		case DEPSNODE_CLASS_OPERATION:
+			return 4;
+		case DEPSNODE_CLASS_COMPONENT:
+			return 1;
+		default:
+			return 9;
+	}
+#endif
+
+#ifdef COLOR_SCHEME_NODE_TYPE
+	const int(*pair)[2];
+	for (pair = deg_debug_node_type_color_map; (*pair)[0] >= 0; ++pair) {
+		if ((*pair)[0] == node->type) {
+			return (*pair)[1];
+		}
+	}
+	return -1;
+#endif
+}
+
+static const char *deg_debug_ogdf_node_color(const DebugContext &ctx, const DepsNode *node)
+{
+	const int color_index = deg_debug_node_color_index(node);
+	const char *defaultcolor = "#DCDCDC";
+	const char *fillcolor = (color_index < 0) ? defaultcolor : deg_debug_colors_light[color_index % deg_debug_max_colors];
+	printf("      color is %s with index %d\n", fillcolor, color_index);
+	return fillcolor;
+}
+
 static void deg_debug_ogdf_node_single(const DebugContext &ctx, const DepsNode *node)
 {
-	const char *shape = "box";
 	string name = node->identifier();
-	float priority = -1.0f;
+	//float priority = -1.0f;
+
+#if 0 // XXX: crashes for now
 	if (node->type == DEPSNODE_TYPE_ID_REF) {
 		IDDepsNode *id_node = (IDDepsNode *)node;
+
 		char buf[256];
 		BLI_snprintf(buf, sizeof(buf), " (Layers: %d)", id_node->layers);
-		name += buf;
-	}
-	if (ctx.show_eval_priority && node->tclass == DEPSNODE_CLASS_OPERATION) {
-		priority = ((OperationDepsNode *)node)->eval_priority;
-	}
 
-#if 0
-	deg_debug_fprintf(ctx, "// %s\n", name.c_str());
-	deg_debug_fprintf(ctx, "\"node_%p\"", node);
-	deg_debug_fprintf(ctx, "[");
-	//	deg_debug_fprintf(ctx, "label=<<B>%s</B>>", name);
-	if (priority >= 0.0f) {
-		deg_debug_fprintf(ctx, "label=<%s<BR/>(<I>%.2f</I>)>",
-			name.c_str(),
-			priority);
-	}
-	else {
-		deg_debug_fprintf(ctx, "label=<%s>", name.c_str());
+		name += buf;
 	}
-	deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname);
-	deg_debug_fprintf(ctx, ",fontsize=%f", deg_debug_graphviz_node_label_size);
-	deg_debug_fprintf(ctx, ",shape=%s", shape);
-	deg_debug_fprintf(ctx, ",style="); deg_debug_graphviz_node_style(ctx, node);
-	deg_debug_fprintf(ctx, ",color="); deg_debug_graphviz_node_color(ctx, node);
-	deg_debug_fprintf(ctx, ",fillcolor="); deg_debug_graphviz_node_fillcolor(ctx, node);
-	deg_debug_fprintf(ctx, ",penwidth="); deg_debug_graphviz_node_penwidth(ctx, node);
-	deg_debug_fprintf(ctx, "];" NL);
-	deg_debug_fprintf(ctx, NL);
 #endif
+	//if (ctx.show_eval_priority && node->tclass == DEPSNODE_CLASS_OPERATION) {
+	//	priority = ((OperationDepsNode *)node)->eval_priority;
+	//}
+
+	/* create node */
+	ogdf::node v = ctx.G->newNode();
+
+	printf("  doing node - %s\n", name.c_str());
+	ctx.GA->labelNode(v) = ogdf::String(name.c_str());
+
+	printf("  with color...\n");
+	ctx.GA->colorNode(v) = ogdf::String(deg_debug_ogdf_node_color(ctx, node)); /* ogdf::Color == ogdf::String */
+	// TODO: style/shape - rounded rect, vs straight-edge, vs ellipse?
+
+	/* add to reference mapping for later reference when building relations */
+	printf("  adding to map\n");
+	ctx.node_map[node] = v;
 }
 
 static void deg_debug_ogdf_node(const DebugContext &ctx, const DepsNode *node)
@@ -204,12 +292,17 @@ static void deg_debug_ogdf_node_relations(const DebugContext &ctx, const DepsNod
 {
 	DEPSNODE_RELATIONS_ITER_BEGIN(node->inlinks, rel)
 	{
-		const DepsNode *tail = rel->to; /* same as node */
 		const DepsNode *head = rel->from;
+		const DepsNode *tail = rel->to; /* same as node */
+
+		ogdf::node head_node = ctx.node_map[head];
+		ogdf::node tail_node = ctx.node_map[tail];
 
-		// XXX: IMPLEMENT ME!
-		(v

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list