[Bf-blender-cvs] [498ca41] object_nodes: Added graphviz debug output for parsed bvm node graphs.
Lukas Tönne
noreply at git.blender.org
Tue Nov 24 09:43:51 CET 2015
Commit: 498ca41b8adf55b939e26f066d1887629088a2fd
Author: Lukas Tönne
Date: Tue Nov 3 13:51:32 2015 +0100
Branches: object_nodes
https://developer.blender.org/rB498ca41b8adf55b939e26f066d1887629088a2fd
Added graphviz debug output for parsed bvm node graphs.
===================================================================
M source/blender/blenvm/BVM_api.h
M source/blender/blenvm/compile/bvm_nodegraph.cc
M source/blender/blenvm/compile/bvm_nodegraph.h
M source/blender/blenvm/intern/bvm_api.cc
M source/blender/makesrna/intern/rna_blenvm.c
M source/blender/makesrna/intern/rna_texture_api.c
===================================================================
diff --git a/source/blender/blenvm/BVM_api.h b/source/blender/blenvm/BVM_api.h
index a91a4ae..b24b217 100644
--- a/source/blender/blenvm/BVM_api.h
+++ b/source/blender/blenvm/BVM_api.h
@@ -32,6 +32,8 @@
* \ingroup bvm
*/
+#include <stdio.h>
+
#include "BVM_types.h"
#ifdef __cplusplus
@@ -114,7 +116,8 @@ void BVM_eval_forcefield(struct BVMEvalGlobals *globals, struct BVMEvalContext *
struct Tex;
struct TexResult;
-struct BVMExpression *BVM_gen_texture_expression(const struct BVMEvalGlobals *globals, struct Tex *tex, struct bNodeTree *btree);
+struct BVMExpression *BVM_gen_texture_expression(const struct BVMEvalGlobals *globals, struct Tex *tex,
+ struct bNodeTree *btree, FILE *debug_file);
void BVM_eval_texture(struct BVMEvalContext *context, struct BVMExpression *expr,
struct TexResult *target,
diff --git a/source/blender/blenvm/compile/bvm_nodegraph.cc b/source/blender/blenvm/compile/bvm_nodegraph.cc
index 3554878..5e02277 100644
--- a/source/blender/blenvm/compile/bvm_nodegraph.cc
+++ b/source/blender/blenvm/compile/bvm_nodegraph.cc
@@ -501,6 +501,10 @@ void NodeGraph::set_output_link(const string &name, NodeInstance *link_node, con
}
}
+/* === DEBUGGING === */
+
+#define NL "\r\n"
+
void NodeGraph::dump(std::ostream &s)
{
s << "NodeGraph\n";
@@ -546,6 +550,142 @@ void NodeGraph::dump(std::ostream &s)
}
}
+static const char *debug_graphviz_fontname = "helvetica";
+static float debug_graphviz_graph_label_size = 20.0f;
+static float debug_graphviz_node_label_size = 14.0f;
+
+struct DebugContext {
+ FILE *file;
+};
+
+static void debug_fprintf(const DebugContext &ctx, const char *fmt, ...) ATTR_PRINTF_FORMAT(2, 3);
+static void debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(ctx.file, fmt, args);
+ va_end(args);
+}
+
+static void debug_graphviz_node(const DebugContext &ctx, const NodeInstance *node)
+{
+ const char *shape = "box";
+ const char *style = "filled,rounded";
+ const char *color = "black";
+ const char *fillcolor = "gainsboro";
+ float penwidth = 1.0f;
+ string name = node->type->name;
+
+ debug_fprintf(ctx, "// %s\n", node->name.c_str());
+ debug_fprintf(ctx, "\"node_%p\"", node);
+ debug_fprintf(ctx, "[");
+
+ /* html label including rows for input/output sockets
+ * http://www.graphviz.org/doc/info/shapes.html#html
+ */
+ debug_fprintf(ctx, "label=<<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"4\">");
+ debug_fprintf(ctx, "<TR><TD COLSPAN=\"2\">%s</TD></TR>", name.c_str());
+ int numin = node->type->inputs.size();
+ int numout = node->type->outputs.size();
+ for (int i = 0; i < numin || i < numout; ++i) {
+ debug_fprintf(ctx, "<TR>");
+
+ if (i < numin) {
+ string name_in = node->type->inputs[i].name;
+ debug_fprintf(ctx, "<TD PORT=\"%s\" BORDER=\"1\">%s</TD>", name_in.c_str(), name_in.c_str());
+ }
+ else
+ debug_fprintf(ctx, "<TD></TD>");
+
+ if (i < numout) {
+ string name_out = node->type->outputs[i].name;
+ debug_fprintf(ctx, "<TD PORT=\"%s\" BORDER=\"1\">%s</TD>", name_out.c_str(), name_out.c_str());
+ }
+ else
+ debug_fprintf(ctx, "<TD></TD>");
+
+ debug_fprintf(ctx, "</TR>");
+ }
+ debug_fprintf(ctx, "</TABLE>>");
+
+ debug_fprintf(ctx, ",fontname=\"%s\"", debug_graphviz_fontname);
+ debug_fprintf(ctx, ",fontsize=\"%f\"", debug_graphviz_node_label_size);
+ debug_fprintf(ctx, ",shape=\"%s\"", shape);
+ debug_fprintf(ctx, ",style=\"%s\"", style);
+ debug_fprintf(ctx, ",color=\"%s\"", color);
+ debug_fprintf(ctx, ",fillcolor=\"%s\"", fillcolor);
+ debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth);
+ debug_fprintf(ctx, "];" NL);
+ debug_fprintf(ctx, NL);
+}
+
+static void debug_graphviz_node_links(const DebugContext &ctx, const NodeInstance *node)
+{
+ for (NodeInstance::InputMap::const_iterator it = node->inputs.begin(); it != node->inputs.end(); ++it) {
+ const NodeInstance::InputInstance &input = it->second;
+
+ if (input.link_node && input.link_socket) {
+ float penwidth = 2.0f;
+
+ const NodeInstance *tail = input.link_node;
+ const string &tail_socket = input.link_socket->name;
+ const NodeInstance *head = node;
+ const string &head_socket = it->first;
+ debug_fprintf(ctx, "// %s:%s -> %s:%s\n",
+ tail->name.c_str(), tail_socket.c_str(),
+ head->name.c_str(), head_socket.c_str());
+ debug_fprintf(ctx, "\"node_%p\":%s", tail, tail_socket.c_str());
+ debug_fprintf(ctx, " -> ");
+ debug_fprintf(ctx, "\"node_%p\":%s", head, head_socket.c_str());
+
+ debug_fprintf(ctx, "[");
+ /* Note: without label an id seem necessary to avoid bugs in graphviz/dot */
+ debug_fprintf(ctx, "id=\"%s\"", (string("A") + head->name.c_str() + "B" + tail->name.c_str()).c_str());
+
+ debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth);
+ debug_fprintf(ctx, "];" NL);
+ debug_fprintf(ctx, NL);
+ }
+ else {
+
+ }
+ }
+}
+
+void NodeGraph::dump_graphviz(FILE *f, const string &label)
+{
+ DebugContext ctx;
+ ctx.file = f;
+
+ debug_fprintf(ctx, "digraph depgraph {" NL);
+ debug_fprintf(ctx, "rankdir=LR;" NL);
+ debug_fprintf(ctx, "graph [");
+ debug_fprintf(ctx, "labelloc=\"t\"");
+ debug_fprintf(ctx, ",fontsize=%f", debug_graphviz_graph_label_size);
+ debug_fprintf(ctx, ",fontname=\"%s\"", debug_graphviz_fontname);
+ debug_fprintf(ctx, ",label=\"%s\"", label.c_str());
+// debug_fprintf(ctx, ",splines=ortho");
+ debug_fprintf(ctx, "];" NL);
+
+ for (NodeInstanceMap::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
+ const NodeInstance *node = &it->second;
+
+ debug_graphviz_node(ctx, node);
+ }
+
+ for (NodeInstanceMap::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
+ const NodeInstance *node = &it->second;
+
+ debug_graphviz_node_links(ctx, node);
+ }
+
+// deg_debug_graphviz_legend(ctx);
+
+ debug_fprintf(ctx, "}" NL);
+}
+
+#undef NL
+
/* ------------------------------------------------------------------------- */
OpCode get_opcode_from_node_type(const string &node)
diff --git a/source/blender/blenvm/compile/bvm_nodegraph.h b/source/blender/blenvm/compile/bvm_nodegraph.h
index 0857fa9..ab0f416 100644
--- a/source/blender/blenvm/compile/bvm_nodegraph.h
+++ b/source/blender/blenvm/compile/bvm_nodegraph.h
@@ -258,6 +258,7 @@ struct NodeGraph {
}
void dump(std::ostream &stream = std::cout);
+ void dump_graphviz(FILE *f, const string &label);
NodeInstanceMap nodes;
InputList inputs;
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index a1f67e7..15101a7 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -451,7 +451,8 @@ static void parse_tex_nodes(CompileContext */*_context*/, bNodeTree *btree, bvm:
}
-struct BVMExpression *BVM_gen_texture_expression(const struct BVMEvalGlobals *globals, struct Tex *tex, bNodeTree *btree)
+struct BVMExpression *BVM_gen_texture_expression(const struct BVMEvalGlobals *globals, struct Tex *tex,
+ bNodeTree *btree, FILE *debug_file)
{
using namespace bvm;
@@ -465,6 +466,10 @@ struct BVMExpression *BVM_gen_texture_expression(const struct BVMEvalGlobals *gl
CompileContext comp(_GLOBALS(globals));
parse_tex_nodes(&comp, btree, &graph);
+ if (debug_file) {
+ graph.dump_graphviz(debug_file, "Texture Expression Graph");
+ }
+
BVMCompiler compiler;
Expression *expr = compiler.codegen_expression(graph);
@@ -530,7 +535,7 @@ struct BVMExpression *BVM_texture_cache_acquire(Tex *tex)
else if (tex->use_nodes && tex->nodetree) {
EvalGlobals globals;
- BVMExpression *expr = BVM_gen_texture_expression((BVMEvalGlobals *)(&globals), tex, tex->nodetree);
+ BVMExpression *expr = BVM_gen_texture_expression((BVMEvalGlobals *)(&globals), tex, tex->nodetree, NULL);
bvm_tex_cache[tex] = _EXPR(expr);
diff --git a/source/blender/makesrna/intern/rna_blenvm.c b/source/blender/makesrna/intern/rna_blenvm.c
index b0dc6bf..78e859d 100644
--- a/source/blender/makesrna/intern/rna_blenvm.c
+++ b/source/blender/makesrna/intern/rna_blenvm.c
@@ -29,6 +29,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_path_util.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -65,6 +67,8 @@ static void rna_BVMNodeGraph_set_output(struct BVMNodeGraph *graph,
return BVM_nodegraph_set_output_link(graph, name, node, socket);
}
+/* ------------------------------------------------------------------------- */
+
static void rna_BVMNodeInstance_set_value_float(struct BVMNodeInstance *node, const char *socket, float value)
{
BVM_node_set_input_value_float(node, socket, value);
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index a27ba6e..2cb8a79 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -44,6 +44,7 @@
#include "BKE_global.h"
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
+#include "BVM_api.h"
static void save_envmap(struct EnvMap *env, bContext *C, ReportList *reports, const char *filepath,
struct Scene *scene, float layout[12])
@@ -82,6 +83,26 @@ static void texture_evaluate(struct Tex *tex, float value[3], float r_color[4])
r_color[3] = texres.tin;
}
+static void rna_Texture_debug_nodes_graphviz(struct Tex *tex, const char *filename)
+{
+ FILE *f = fopen(filename, "w");
+ if (f == NULL)
+ return;
+
+ if (tex->nodetree && tex->use_nodes) {
+ struct BVMEvalGlobals *globals;
+ struct BVMExpression *expr;
+
+ globals = BVM_globals_create();
+ expr = BVM_gen_texture_expression(globals, tex, tex->nodetree, f);
+
+ BVM_expression_free(expr);
+ BVM_globals_free(globals);
+ }
+
+ fclose(f);
+}
+
#else
void RNA_api_texture(StructRNA *srna)
@@ -100,6 +121,10 @@ void RNA_api_texture(StructRNA *srna)
RNA_def_property_flag(parm, PROP_THICK_WRAP);
RNA_def_function_output(func, parm);
+ func = RNA_def_function(srna, "debug_nodes_graphviz", "rna_Texture_debug_nodes_graphviz");
+ parm = RNA_def_string_file_path(func, "filename", NULL,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list