From f88501a44d1f519539d056a7d1f240d126a5071a Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Wed, 4 Jan 2012 00:23:34 +0000 Subject: Added two stroke geometry modifiers: - 2D Offset: Adds two-dimensional offsets to stroke backbone geometry. - 2D Transform: Applies two-dimensional scaling and rotation to stroke backbone geometry. --- .../freestyle/style_modules/parameter_editor.py | 94 ++++++++++++++++++++++ release/scripts/startup/bl_ui/properties_render.py | 21 +++++ source/blender/blenkernel/intern/linestyle.c | 50 +++++++++++- source/blender/blenloader/intern/writefile.c | 6 ++ source/blender/makesdna/DNA_linestyle_types.h | 31 ++++++- source/blender/makesrna/RNA_access.h | 2 + source/blender/makesrna/intern/rna_linestyle.c | 79 ++++++++++++++++++ 7 files changed, 281 insertions(+), 2 deletions(-) diff --git a/release/scripts/freestyle/style_modules/parameter_editor.py b/release/scripts/freestyle/style_modules/parameter_editor.py index 421ca058a53..a4b349b751e 100644 --- a/release/scripts/freestyle/style_modules/parameter_editor.py +++ b/release/scripts/freestyle/style_modules/parameter_editor.py @@ -493,6 +493,94 @@ class PerlinNoise2DShader(StrokeShader): it.increment() stroke.UpdateLength() +class Offset2DShader(StrokeShader): + def __init__(self, start, end, x, y): + StrokeShader.__init__(self) + self.__start = start + self.__end = end + self.__xy = Vector([x, y]) + self.__getNormal = Normal2DF0D() + def getName(self): + return "Offset2DShader" + def shade(self, stroke): + it = stroke.strokeVerticesBegin() + while not it.isEnd(): + v = it.getObject() + u = v.u() + a = self.__start + u * (self.__end - self.__start) + n = self.__getNormal(it.castToInterface0DIterator()) + n = n * a + p = v.getPoint() + v.setPoint(p + n + self.__xy) + it.increment() + stroke.UpdateLength() + +class Transform2DShader(StrokeShader): + def __init__(self, pivot, scale_x, scale_y, angle, pivot_u, pivot_x, pivot_y): + StrokeShader.__init__(self) + self.__pivot = pivot + self.__scale_x = scale_x + self.__scale_y = scale_y + self.__angle = angle + self.__pivot_u = pivot_u + self.__pivot_x = pivot_x + self.__pivot_y = pivot_y + def getName(self): + return "Transform2DShader" + def shade(self, stroke): + # determine the pivot of scaling and rotation operations + if self.__pivot == "START": + it = stroke.strokeVerticesBegin() + pivot = it.getObject().getPoint() + elif self.__pivot == "END": + it = stroke.strokeVerticesEnd() + it.decrement() + pivot = it.getObject().getPoint() + elif self.__pivot == "PARAM": + p = None + it = stroke.strokeVerticesBegin() + while not it.isEnd(): + prev = p + v = it.getObject() + p = v.getPoint() + u = v.u() + if self.__pivot_u < u: + break + it.increment() + if prev is None: + pivot = p + else: + delta = u - self.__pivot_u + pivot = p + delta * (prev - p) + elif self.__pivot == "CENTER": + pivot = Vector([0.0, 0.0]) + n = 0 + it = stroke.strokeVerticesBegin() + while not it.isEnd(): + p = it.getObject().getPoint() + pivot = pivot + p + n = n + 1 + it.increment() + pivot.x = pivot.x / n + pivot.y = pivot.y / n + elif self.__pivot == "ABSOLUTE": + pivot = Vector([self.__pivot_x, self.__pivot_y]) + # apply scaling and rotation operations + cos_theta = math.cos(math.pi * self.__angle / 180.0) + sin_theta = math.sin(math.pi * self.__angle / 180.0) + it = stroke.strokeVerticesBegin() + while not it.isEnd(): + v = it.getObject() + p = v.getPoint() + p = p - pivot + x = p.x * self.__scale_x + y = p.y * self.__scale_y + p.x = x * cos_theta - y * sin_theta + p.y = x * sin_theta + y * cos_theta + v.setPoint(p + pivot) + it.increment() + stroke.UpdateLength() + # Predicates and helper functions class QuantitativeInvisibilityRangeUP1D(UnaryPredicate1D): @@ -1035,6 +1123,12 @@ def process(layer_name, lineset_name): elif m.shape == "SQUARES": shaders_list.append(pyBluePrintSquaresShader( m.rounds, m.backbone_length, m.random_backbone)) + elif m.type == "2D_OFFSET": + shaders_list.append(Offset2DShader( + m.start, m.end, m.x, m.y)) + elif m.type == "2D_TRANSFORM": + shaders_list.append(Transform2DShader( + m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y)) color = linestyle.color shaders_list.append(ConstantColorShader(color.r, color.g, color.b, linestyle.alpha)) shaders_list.append(ConstantThicknessShader(linestyle.thickness)) diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 961513f14d6..8ac178edcb1 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -571,6 +571,27 @@ class RENDER_PT_freestyle_linestyle(RenderButtonsPanel, Panel): box.prop(modifier, "backbone_length") box.prop(modifier, "random_backbone") + elif modifier.type == "2D_OFFSET": + row = box.row(align=True) + row.prop(modifier, "start") + row.prop(modifier, "end") + row = box.row(align=True) + row.prop(modifier, "x") + row.prop(modifier, "y") + + elif modifier.type == "2D_TRANSFORM": + box.prop(modifier, "pivot") + if modifier.pivot == "PARAM": + box.prop(modifier, "pivot_u") + elif modifier.pivot == "ABSOLUTE": + row = box.row(align=True) + row.prop(modifier, "pivot_x") + row.prop(modifier, "pivot_y") + row = box.row(align=True) + row.prop(modifier, "scale_x") + row.prop(modifier, "scale_y") + box.prop(modifier, "angle") + def draw(self, context): layout = self.layout diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index 3afdef79231..dcacfeea5bc 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -65,7 +65,9 @@ static char *modifier_name[LS_MODIFIER_NUM] = { "Calligraphy", "Polygonalization", "Guiding Lines", - "Blueprint"}; + "Blueprint", + "2D Offset", + "2D Transform"}; static void default_linestyle_settings(FreestyleLineStyle *linestyle) { @@ -636,6 +638,12 @@ static LineStyleModifier *alloc_geometry_modifier(int type) case LS_MODIFIER_BLUEPRINT: size = sizeof(LineStyleGeometryModifier_Blueprint); break; + case LS_MODIFIER_2D_OFFSET: + size = sizeof(LineStyleGeometryModifier_2DOffset); + break; + case LS_MODIFIER_2D_TRANSFORM: + size = sizeof(LineStyleGeometryModifier_2DTransform); + break; default: return NULL; /* unknown modifier type */ } @@ -699,6 +707,21 @@ LineStyleModifier *FRS_add_linestyle_geometry_modifier(FreestyleLineStyle *lines ((LineStyleGeometryModifier_Blueprint *)m)->random_center = 5; ((LineStyleGeometryModifier_Blueprint *)m)->random_backbone = 5; break; + case LS_MODIFIER_2D_OFFSET: + ((LineStyleGeometryModifier_2DOffset *)m)->start = 0.f; + ((LineStyleGeometryModifier_2DOffset *)m)->end = 0.f; + ((LineStyleGeometryModifier_2DOffset *)m)->x = 0.f; + ((LineStyleGeometryModifier_2DOffset *)m)->y = 0.f; + break; + case LS_MODIFIER_2D_TRANSFORM: + ((LineStyleGeometryModifier_2DTransform *)m)->pivot = LS_MODIFIER_2D_TRANSFORM_PIVOT_CENTER; + ((LineStyleGeometryModifier_2DTransform *)m)->scale_x = 1.f; + ((LineStyleGeometryModifier_2DTransform *)m)->scale_y = 1.f; + ((LineStyleGeometryModifier_2DTransform *)m)->angle = 0.f; + ((LineStyleGeometryModifier_2DTransform *)m)->pivot_u = 0.5f; + ((LineStyleGeometryModifier_2DTransform *)m)->pivot_x = 0.f; + ((LineStyleGeometryModifier_2DTransform *)m)->pivot_y = 0.f; + break; default: return NULL; /* unknown modifier type */ } @@ -798,6 +821,27 @@ LineStyleModifier *FRS_copy_linestyle_geometry_modifier(FreestyleLineStyle *line ((LineStyleGeometryModifier_Blueprint *)new_m)->random_backbone = p->random_backbone; } break; + case LS_MODIFIER_2D_OFFSET: + { + LineStyleGeometryModifier_2DOffset *p = (LineStyleGeometryModifier_2DOffset *)m; + ((LineStyleGeometryModifier_2DOffset *)new_m)->start = p->start; + ((LineStyleGeometryModifier_2DOffset *)new_m)->end = p->end; + ((LineStyleGeometryModifier_2DOffset *)new_m)->x = p->x; + ((LineStyleGeometryModifier_2DOffset *)new_m)->y = p->y; + } + break; + case LS_MODIFIER_2D_TRANSFORM: + { + LineStyleGeometryModifier_2DTransform *p = (LineStyleGeometryModifier_2DTransform *)m; + ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot = p->pivot; + ((LineStyleGeometryModifier_2DTransform *)new_m)->scale_x = p->scale_x; + ((LineStyleGeometryModifier_2DTransform *)new_m)->scale_y = p->scale_y; + ((LineStyleGeometryModifier_2DTransform *)new_m)->angle = p->angle; + ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot_u = p->pivot_u; + ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot_x = p->pivot_x; + ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot_y = p->pivot_y; + } + break; default: return NULL; /* unknown modifier type */ } @@ -831,6 +875,10 @@ void FRS_remove_linestyle_geometry_modifier(FreestyleLineStyle *linestyle, LineS break; case LS_MODIFIER_BLUEPRINT: break; + case LS_MODIFIER_2D_OFFSET: + break; + case LS_MODIFIER_2D_TRANSFORM: + break; } BLI_freelinkN(&linestyle->geometry_modifiers, m); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 454078fc748..015b74e5a7d 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2761,6 +2761,12 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier case LS_MODIFIER_BLUEPRINT: struct_name = "LineStyleGeometryModifier_Blueprint"; break; + case LS_MODIFIER_2D_OFFSET: + struct_name = "LineStyleGeometryModifier_2DOffset"; + break; + case LS_MODIFIER_2D_TRANSFORM: + struct_name = "LineStyleGeometryModifier_2DTransform"; + break; default: struct_name = "LineStyleGeometryModifier"; // this should not happen } diff --git a/source/blender/makesdna/DNA_linestyle_types.h b/source/blender/makesdna/DNA_linestyle_types.h index 4ae3183e454..1c82443e357 100644 --- a/source/blender/makesdna/DNA_linestyle_types.h +++ b/source/blender/makesdna/DNA_linestyle_types.h @@ -65,7 +65,9 @@ typedef struct LineStyleModifier { #define LS_MODIFIER_POLYGONIZATION 14 #define LS_MODIFIER_GUIDING_LINES 15 #define LS_MODIFIER_BLUEPRINT 16 -#define LS_MODIFIER_NUM 17 +#define LS_MODIFIER_2D_OFFSET 17 +#define LS_MODIFIER_2D_TRANSFORM 18 +#define LS_MODIFIER_NUM 19 /* LineStyleModifier::flags */ #define LS_MODIFIER_ENABLED 1 @@ -331,6 +333,33 @@ typedef struct LineStyleGeometryModifier_Blueprint { } LineStyleGeometryModifier_Blueprint; +typedef struct LineStyleGeometryModifier_2DOffset { + struct LineStyleModifier modifier; + + float start, end; + float x, y; + +} LineStyleGeometryModifier_2DOffset; + +/* LineStyleGeometryModifier_2DTransform::pivot */ +#define LS_MODIFIER_2D_TRANSFORM_PIVOT_CENTER 1 +#define LS_MODIFIER_2D_TRANSFORM_PIVOT_START 2 +#define LS_MODIFIER_2D_TRANSFORM_PIVOT_END 3 +#define LS_MODIFIER_2D_TRANSFORM_PIVOT_PARAM 4 +#define LS_MODIFIER_2D_TRANSFORM_PIVOT_ABSOLUTE 5 + +typedef struct LineStyleGeometryModifier_2DTransform { + struct LineStyleModifier modifier; + + int pivot; + float scale_x, scale_y; + float angle; + float pivot_u; + float pivot_x, pivot_y; + int pad; + +} LineStyleGeometryModifier_2DTransform; + /* Calligraphic thickness modifier */ typedef struct LineStyleThicknessModifier_Calligraphy { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 75a730a23cb..bff1c214b4f 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -302,6 +302,8 @@ extern StructRNA RNA_LineStyleColorModifier_DistanceFromCamera; extern StructRNA RNA_LineStyleColorModifier_DistanceFromObject; extern StructRNA RNA_LineStyleColorModifier_Material; extern StructRNA RNA_LineStyleGeometryModifier; +extern StructRNA RNA_LineStyleGeometryModifier_2DOffset; +extern StructRNA RNA_LineStyleGeometryModifier_2DTransform; extern StructRNA RNA_LineStyleGeometryModifier_BackboneStretcher; extern StructRNA RNA_LineStyleGeometryModifier_BezierCurve; extern StructRNA RNA_LineStyleGeometryModifier_Blueprint; diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c index 07dd7e00a53..0a206cbc36e 100644 --- a/source/blender/makesrna/intern/rna_linestyle.c +++ b/source/blender/makesrna/intern/rna_linestyle.c @@ -59,6 +59,8 @@ EnumPropertyItem linestyle_thickness_modifier_type_items[] ={ {0, NULL, 0, NULL, NULL}}; EnumPropertyItem linestyle_geometry_modifier_type_items[] ={ + {LS_MODIFIER_2D_OFFSET, "2D_OFFSET", ICON_MODIFIER, "2D Offset", ""}, + {LS_MODIFIER_2D_TRANSFORM, "2D_TRANSFORM", ICON_MODIFIER, "2D Transform", ""}, {LS_MODIFIER_BACKBONE_STRETCHER, "BACKBONE_STRETCHER", ICON_MODIFIER, "Backbone Stretcher", ""}, {LS_MODIFIER_BEZIER_CURVE, "BEZIER_CURVE", ICON_MODIFIER, "Bezier Curve", ""}, {LS_MODIFIER_BLUEPRINT, "BLUEPRINT", ICON_MODIFIER, "Blueprint", ""}, @@ -159,6 +161,10 @@ static StructRNA *rna_LineStyle_geometry_modifier_refine(struct PointerRNA *ptr) return &RNA_LineStyleGeometryModifier_GuidingLines; case LS_MODIFIER_BLUEPRINT: return &RNA_LineStyleGeometryModifier_Blueprint; + case LS_MODIFIER_2D_OFFSET: + return &RNA_LineStyleGeometryModifier_2DOffset; + case LS_MODIFIER_2D_TRANSFORM: + return &RNA_LineStyleGeometryModifier_2DTransform; default: return &RNA_LineStyleGeometryModifier; } @@ -431,6 +437,14 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna) {LS_MODIFIER_BLUEPRINT_SQUARES, "SQUARES", 0, "Squares", "Draw a blueprint using square contour strokes"}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem transform_pivot_items[] = { + {LS_MODIFIER_2D_TRANSFORM_PIVOT_CENTER, "CENTER", 0, "Stroke Center", ""}, + {LS_MODIFIER_2D_TRANSFORM_PIVOT_START, "START", 0, "Stroke Start", ""}, + {LS_MODIFIER_2D_TRANSFORM_PIVOT_END, "END", 0, "Stroke End", ""}, + {LS_MODIFIER_2D_TRANSFORM_PIVOT_PARAM, "PARAM", 0, "Stroke Point Parameter", ""}, + {LS_MODIFIER_2D_TRANSFORM_PIVOT_ABSOLUTE, "ABSOLUTE", 0, "Absolute 2D Point", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "LineStyleModifier", NULL); RNA_def_struct_ui_text(srna, "Line Style Modifier", "Base type to define modifiers"); @@ -772,6 +786,71 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Random Backbone", "Randomness of the backbone stretching"); RNA_def_property_update(prop, NC_SCENE, NULL); + srna= RNA_def_struct(brna, "LineStyleGeometryModifier_2DOffset", "LineStyleGeometryModifier"); + RNA_def_struct_ui_text(srna, "2D Offset", "Add two-dimensional offsets to stroke backbone geometry"); + rna_def_geometry_modifier(srna); + + prop= RNA_def_property(srna, "start", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "start"); + RNA_def_property_ui_text(prop, "Start", "Displacement that is applied from the beginning of the stroke"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "end", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "end"); + RNA_def_property_ui_text(prop, "End", "Displacement that is applied from the end of the stroke"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "x"); + RNA_def_property_ui_text(prop, "X", "Displacement that is applied to the X coordinates of stroke vertices"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "y"); + RNA_def_property_ui_text(prop, "Y", "Displacement that is applied to the Y coordinates of stroke vertices"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + srna= RNA_def_struct(brna, "LineStyleGeometryModifier_2DTransform", "LineStyleGeometryModifier"); + RNA_def_struct_ui_text(srna, "2D Transform", "Apply two-dimensional scaling and rotation to stroke backbone geometry"); + rna_def_geometry_modifier(srna); + + prop= RNA_def_property(srna, "pivot", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "pivot"); + RNA_def_property_enum_items(prop, transform_pivot_items); + RNA_def_property_ui_text(prop, "Pivot", "Pivot of scaling and rotation operations"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "scale_x"); + RNA_def_property_ui_text(prop, "Scale X", "Scaling factor that is applied along the X axis"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "scale_y"); + RNA_def_property_ui_text(prop, "Scale Y", "Scaling factor that is applied along the Y axis"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "angle"); + RNA_def_property_ui_text(prop, "Rotation Angle", "Rotation angle in degrees"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "pivot_u", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "pivot_u"); + RNA_def_property_range(prop, 0.f, 1.f); + RNA_def_property_ui_text(prop, "Stroke Point Parameter", "Pivot in terms of the stroke point parameter u (0 <= u <= 1)"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "pivot_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "pivot_x"); + RNA_def_property_ui_text(prop, "Pivot X", "2D X coordinate of the absolute pivot"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "pivot_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "pivot_y"); + RNA_def_property_ui_text(prop, "Pivot Y", "2D Y coordinate of the absolute pivot"); + RNA_def_property_update(prop, NC_SCENE, NULL); + } static void rna_def_linestyle(BlenderRNA *brna) -- cgit v1.2.3