forked from bartvdbraak/blender
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:
parent
b8a67c2362
commit
f88501a44d
@ -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))
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user