[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38957] branches/soc-2011-onion: basic parser for version 2 MyPaint myp files.

Jason Wilkins Jason.A.Wilkins at gmail.com
Tue Aug 2 23:29:34 CEST 2011


Revision: 38957
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38957
Author:   jwilkins
Date:     2011-08-02 21:29:33 +0000 (Tue, 02 Aug 2011)
Log Message:
-----------
basic parser for version 2 MyPaint myp files.  

version 1 files definitely won't work.

there are lots of typos in the files distributed with mypaint, apparently mypaint is tolerant of these, making the affected values take on their defaults

A lot of brushes work well even though aspect ratio, blending, rake, and many other features are not connected yet.  Some other brushes do not work so well, like the experimental 'fur' and 'dna' brushes.  right now you have to watch the console window for parse errors and make sure that VBO is enabled to see anything.

it is a bit laggy on my 6 year old machine and the debug build.

Modified Paths:
--------------
    branches/soc-2011-onion/release/scripts/startup/bl_ui/space_view3d_toolbar.py
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.cpp
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.h
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_stroke.c
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_stroke.h
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_vertex.c
    branches/soc-2011-onion/source/blender/editors/sculpt_paint/sculpt_tools.c
    branches/soc-2011-onion/source/blender/makesdna/DNA_brush_types.h
    branches/soc-2011-onion/source/blender/makesrna/intern/rna_brush.c

Modified: branches/soc-2011-onion/release/scripts/startup/bl_ui/space_view3d_toolbar.py
===================================================================
--- branches/soc-2011-onion/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2011-08-02 18:56:03 UTC (rev 38956)
+++ branches/soc-2011-onion/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2011-08-02 21:29:33 UTC (rev 38957)
@@ -904,8 +904,11 @@
 
             col.prop(brush, "stroke_method", text="")
 
-            col.prop(brush, "use_brushlib")
+            col.prop(brush, "use_brushlib", text="MyPaint BrushLib")
 
+            if brush.use_brushlib:
+                col.prop(brush, "brushlib_filepath", text="")
+
             # Airbrush
 
             if db:

Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.cpp
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.cpp	2011-08-02 18:56:03 UTC (rev 38956)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.cpp	2011-08-02 21:29:33 UTC (rev 38957)
@@ -156,8 +156,16 @@
 #include <surface.hpp>
 #include <brush.hpp>
 
+#include "BLI_string.h"
+#include "BLI_path_util.h"
 
+#include "BKE_global.h"
+#include "BKE_main.h"
 
+#include <iostream>
+#include <fstream>
+
+
 class BlenderSurface : public Surface {
 public:
 
@@ -345,11 +353,304 @@
 	}
 };
 
+static bool whitespace(std::ifstream &infile)
+{
+	char ch;
 
-struct BrushLibBrush *paint_brushlib_new_brush(float x, float y)
+	do {
+		infile.get(ch);
+
+		if (ch == '#') {
+			do {
+				infile.get(ch);
+			} while (!infile.eof() && ch != '\n');
+		}
+	} while (!infile.eof() && isspace(ch));
+
+	infile.unget();
+
+	return true;
+}
+
+static bool parse_id(std::ifstream &infile, char *out, int max_size)
 {
+	if (!whitespace(infile))
+		return false;
+
+	char ch;
+	int n= 0;
+
+	assert(max_size > 1);
+
+	out[0]= 0;
+
+	infile.get(ch);
+
+	if (infile.eof() || !(isalpha(ch) || ch == '_'))
+		return false;
+
+	out[n++]= ch;
+
+	for (;;) {
+		infile.get(ch);
+
+		if (!(isalnum(ch) || ch == '_') || infile.eof())
+			break;
+
+		if (n < max_size)
+			out[n]= ch;
+
+		n++;
+	}
+
+	out[MIN(n, max_size-1)]= 0;
+
+	infile.unget();
+
+	printf("got: %s\n", out);
+
+	return n <= max_size;
+}
+
+static bool parse_num(std::ifstream &infile, float &out)
+{
+	if (!whitespace(infile))
+		return false;
+
+	infile >> out;
+
+	return !infile.fail();
+}
+
+static bool parse_optional(std::ifstream &infile, const char want)
+{
+	if (!whitespace(infile))
+		return false;
+
+	char ch;
+
+	infile.get(ch);
+
+	if (ch == want) {
+		return true;
+	}
+	else {
+		infile.unget();
+		return false;
+	}
+}
+
+static bool parse_match(std::ifstream &infile, const char want)
+{
+	if (!whitespace(infile))
+		return false;
+
+	char ch;
+
+	infile.get(ch);
+
+	return ch == want;
+}
+
+static void parse_message(const char *msg)
+{
+	printf("MyPaint brush parser: %s", msg);
+}
+
+static void parse_expected(const char *wanted)
+{
+	parse_message("");
+	printf("expected %s.\n", wanted);
+}
+
+static int load_brush(Brush *brush, const char *filepath)
+{
+	struct entry_t { const char *name; int index; };
+
+	std::ifstream infile(filepath);
+
+	if (infile) {
+		while (!infile.eof()) {
+			static const int MAX_SIZE= 100;
+			char id_name[MAX_SIZE];
+
+			if (!parse_id(infile, id_name, MAX_SIZE)) {
+				parse_expected("id name");
+				return 0;
+			}
+
+			if (strcmp(id_name, "version") == 0) {
+				float version;
+				
+				if (!parse_num(infile, version))
+					return 0;
+
+				if (version != 2) {
+					parse_message("can only accept version 2.\n");
+					return 0;
+				}
+			}
+			else {
+				int id;
+				for (id= 0; id < BRUSH_SETTINGS_COUNT; id++) {
+
+					static const entry_t id_table[BRUSH_SETTINGS_COUNT+1]= {
+						{ "opaque", BRUSH_OPAQUE },
+						{ "opaque_multiply", BRUSH_OPAQUE_MULTIPLY },
+						{ "opaque_linearize", BRUSH_OPAQUE_LINEARIZE },
+						{ "radius_logarithmic", BRUSH_RADIUS_LOGARITHMIC },
+						{ "hardness", BRUSH_HARDNESS },
+						{ "dabs_per_basic_radius", BRUSH_DABS_PER_BASIC_RADIUS },
+						{ "dabs_per_actual_radius", BRUSH_DABS_PER_ACTUAL_RADIUS },
+						{ "dabs_per_second", BRUSH_DABS_PER_SECOND },
+						{ "radius_by_random", BRUSH_RADIUS_BY_RANDOM },
+						{ "speed1_slowness", BRUSH_SPEED1_SLOWNESS },
+						{ "speed2_slowness", BRUSH_SPEED2_SLOWNESS },
+						{ "speed1_gamma", BRUSH_SPEED1_GAMMA },
+						{ "speed2_gamma", BRUSH_SPEED2_GAMMA },
+						{ "offset_by_random", BRUSH_OFFSET_BY_RANDOM },
+						{ "offset_by_speed", BRUSH_OFFSET_BY_SPEED },
+						{ "offset_by_speed_slowness", BRUSH_OFFSET_BY_SPEED_SLOWNESS },
+						{ "slow_tracking", BRUSH_SLOW_TRACKING },
+						{ "slow_tracking_per_dab", BRUSH_SLOW_TRACKING_PER_DAB },
+						{ "tracking_noise", BRUSH_TRACKING_NOISE },
+						{ "color_h", BRUSH_COLOR_H },
+						{ "color_s", BRUSH_COLOR_S },
+						{ "color_v", BRUSH_COLOR_V },
+						{ "change_color_h", BRUSH_CHANGE_COLOR_H },
+						{ "change_color_l", BRUSH_CHANGE_COLOR_L },
+						{ "change_color_hsl_s", BRUSH_CHANGE_COLOR_HSL_S },
+						{ "change_color_v", BRUSH_CHANGE_COLOR_V },
+						{ "change_color_hsv_s", BRUSH_CHANGE_COLOR_HSV_S },
+						{ "smudge", BRUSH_SMUDGE },
+						{ "smudge_radius_log", BRUSH_SMUDGE_RADIUS_LOG },
+						{ "smudge_length", BRUSH_SMUDGE_LENGTH },
+						{ "eraser", BRUSH_ERASER },
+						{ "stroke_threshold", BRUSH_STROKE_THRESHOLD },
+						{ "stroke_treshold", BRUSH_STROKE_THRESHOLD }, /* XXX: very common typo in myp files! */
+						{ "stroke_duration_logarithmic", BRUSH_STROKE_DURATION_LOGARITHMIC },
+						{ "stroke_holdtime", BRUSH_STROKE_HOLDTIME },
+						{ "custom_input", BRUSH_CUSTOM_INPUT },
+						{ "custom_input_slowness", BRUSH_CUSTOM_INPUT_SLOWNESS },
+						{ "elliptical_dab_ratio", BRUSH_ELLIPTICAL_DAB_RATIO },
+						{ "elliptical_dab_angle", BRUSH_ELLIPTICAL_DAB_ANGLE },
+						{ "direction_filter", BRUSH_DIRECTION_FILTER },
+						{ "lock_alpha", BRUSH_LOCK_ALPHA },
+					};
+
+					if (strcmp(id_name, id_table[id].name) == 0) {
+						float base_value;
+						
+						if (!parse_num(infile, base_value))
+							return 0;
+
+						brush->set_base_value(id_table[id].index, base_value);
+
+						while (parse_optional(infile, '|')) {
+							char input_name[MAX_SIZE];
+							
+							if (!parse_id(infile, input_name, MAX_SIZE)) {
+								parse_expected("input name");
+								return 0;
+							}
+
+							int input;
+							for (input= 0; input < INPUT_COUNT; input++) {
+
+								static const entry_t input_table[INPUT_COUNT]= {
+									{ "pressure", INPUT_PRESSURE },
+									{ "speed1", INPUT_SPEED1 },
+									{ "speed2", INPUT_SPEED2 },
+									{ "random", INPUT_RANDOM },
+									{ "stroke", INPUT_STROKE },
+									{ "direction", INPUT_DIRECTION },
+									{ "tilt_declination", INPUT_TILT_DECLINATION },
+									{ "tilt_ascension", INPUT_TILT_ASCENSION },
+									{ "custom", INPUT_CUSTOM },
+								};
+
+								if (strcmp(input_name, input_table[input].name) == 0) {
+									static const int POINT_MAX= 20;
+									float xy[POINT_MAX][2];
+									int n= 0;
+
+									do {
+										if (!parse_match(infile, '('))
+											return 0;
+
+										if (!parse_num(infile, xy[n][0]))
+											return 0;
+
+										if (!parse_num(infile, xy[n][1]))
+											return 0;
+
+										if (!parse_match(infile, ')'))
+											return 0;
+
+										n++;
+
+										assert(n < POINT_MAX);
+
+									} while (parse_optional(infile, ','));
+
+									brush->set_mapping_n(id_table[id].index, input_table[input].index, n);
+
+									for (int index= 0; index < n; index++)
+										brush->set_mapping_point(id_table[id].index, input_table[input].index, index, xy[index][0], xy[index][1]);
+
+									break; // input found
+								}
+							}
+
+							if (input == INPUT_COUNT) {
+								// unknown input
+								parse_expected("input name");
+								return 0;
+							}
+						}
+
+						break; // id found
+					}
+				}
+
+				if (id == BRUSH_SETTINGS_COUNT) {
+					// unknown id
+					parse_expected("id name");
+					return 0;
+				}
+			}
+		}
+
+		return 1;
+	}
+	else {
+		parse_message("cannot open file\n");
+		return 0;
+	}
+}
+
+struct BrushLibBrush *paint_brushlib_new_brush(float x, float y, const char *filepath_in)
+{
 	Brush *brush= new Brush();
 
+	char filepath[240];
+	BLI_strncpy(filepath, filepath_in, sizeof(filepath));
+	BLI_path_abs(filepath, G.main->name);
+
+	if (load_brush(brush, filepath)) {
+		brush->set_state(STATE_X, x);
+		brush->set_state(STATE_Y, y);
+
+		return reinterpret_cast<BrushLibBrush *>(brush);
+	}
+	else {
+		parse_message("failed\n");
+
+		delete brush;
+
+		return 0;
+	}
+
 #if 0
 	brush->set_base_value(BRUSH_OPAQUE, 1.0);
 	brush->set_base_value(BRUSH_OPAQUE_MULTIPLY, 0.0);
@@ -471,7 +772,7 @@
 	brush->set_base_value(BRUSH_CUSTOM_INPUT_SLOWNESS, 0.0);
 #endif
 
-#if 1
+#if 0
 	brush->set_base_value(BRUSH_OPAQUE, 1.0);
 	brush->set_mapping_n(BRUSH_OPAQUE, INPUT_STROKE, 3);
 	brush->set_mapping_point(BRUSH_OPAQUE, INPUT_STROKE, 0, 0.000000, 0.000000);
@@ -545,11 +846,6 @@
 	brush->set_base_value(BRUSH_CUSTOM_INPUT, 0.0);
 	brush->set_base_value(BRUSH_CUSTOM_INPUT_SLOWNESS, 0.0);
 #endif
-
-	brush->set_state(STATE_X, x);
-	brush->set_state(STATE_Y, y);
-
-	return reinterpret_cast<BrushLibBrush *>(brush);
 }
 
 void paint_brushlib_set_radius(

Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.h
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.h	2011-08-02 18:56:03 UTC (rev 38956)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_brushlib.h	2011-08-02 21:29:33 UTC (rev 38957)
@@ -127,7 +127,7 @@
 /* BrushLibBrush and BrushLibSurface are opaque handles
    There is no struct definition */
 
-struct BrushLibBrush *paint_brushlib_new_brush(float x, float y);
+struct BrushLibBrush *paint_brushlib_new_brush(float x, float y, const char *filepath);
 void paint_brushlib_set_radius(struct BrushLibBrush *brush, float radius2d);
 
 void paint_brushlib_set_color(

Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_stroke.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_stroke.c	2011-08-02 18:56:03 UTC (rev 38956)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_stroke.c	2011-08-02 21:29:33 UTC (rev 38957)
@@ -792,7 +792,7 @@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list