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.
This commit is contained in:
Tamito Kajiyama 2012-01-04 00:23:34 +00:00
parent b8a67c2362
commit f88501a44d
7 changed files with 281 additions and 2 deletions

View File

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

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

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

View File

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