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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to