Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/freestyle/style_modules/parameter_editor.py105
-rw-r--r--release/scripts/ui/properties_render.py6
-rw-r--r--source/blender/blenkernel/intern/linestyle.c2
-rw-r--r--source/blender/makesdna/DNA_linestyle_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c16
5 files changed, 135 insertions, 5 deletions
diff --git a/release/scripts/freestyle/style_modules/parameter_editor.py b/release/scripts/freestyle/style_modules/parameter_editor.py
index 8b43fd0e9f1..fe53c2e5152 100644
--- a/release/scripts/freestyle/style_modules/parameter_editor.py
+++ b/release/scripts/freestyle/style_modules/parameter_editor.py
@@ -17,6 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
import Freestyle
+import math
from freestyle_init import *
from logical_operators import *
@@ -298,6 +299,99 @@ def join_unary_predicates(upred_list, bpred):
upred = bpred(upred, p)
return upred
+# Stroke caps
+
+def iter_stroke_vertices(stroke):
+ it = stroke.strokeVerticesBegin()
+ while not it.isEnd():
+ yield it.getObject()
+ it.increment()
+
+class RoundCapShader(StrokeShader):
+ def round_cap_thickness(self, x):
+ x = max(0.0, min(x, 1.0))
+ return math.sqrt(1.0 - (x ** 2))
+ def shade(self, stroke):
+ # save the location and attribute of stroke vertices
+ buffer = []
+ for sv in iter_stroke_vertices(stroke):
+ buffer.append((sv.getPoint(), sv.attribute()))
+ # calculate the number of additional vertices to form caps
+ R, L = stroke[0].attribute().getThicknessRL()
+ caplen_beg = (R + L) / 2.0
+ nverts_beg = max(5, int(R + L))
+ R, L = stroke[-1].attribute().getThicknessRL()
+ caplen_end = (R + L) / 2.0
+ nverts_end = max(5, int(R + L))
+ # increase the total number of stroke vertices
+ nverts = stroke.strokeVerticesSize()
+ stroke.Resample(nverts + nverts_beg + nverts_end)
+ # restore the location and attribute of the original vertices
+ for i in range(nverts):
+ p, attr = buffer[i]
+ stroke[nverts_beg + i].setPoint(p)
+ stroke[nverts_beg + i].setAttribute(attr)
+ # reshape the cap at the beginning of the stroke
+ q, attr = buffer[1]
+ p, attr = buffer[0]
+ d = p - q
+ d = d / d.length * caplen_beg
+ n = 1.0 / nverts_beg
+ R, L = attr.getThicknessRL()
+ for i in range(nverts_beg):
+ t = (nverts_beg - i) * n
+ stroke[i].setPoint(p + d * t)
+ r = self.round_cap_thickness((nverts_beg - i + 1) * n)
+ stroke[i].setAttribute(attr)
+ stroke[i].attribute().setThickness(R * r, L * r)
+ # reshape the cap at the end of the stroke
+ q, attr = buffer[-2]
+ p, attr = buffer[-1]
+ d = p - q
+ d = d / d.length * caplen_end
+ n = 1.0 / nverts_end
+ R, L = attr.getThicknessRL()
+ for i in range(nverts_end):
+ t = (nverts_end - i) * n
+ stroke[-i-1].setPoint(p + d * t)
+ r = self.round_cap_thickness((nverts_end - i + 1) * n)
+ stroke[-i-1].setAttribute(attr)
+ stroke[-i-1].attribute().setThickness(R * r, L * r)
+
+class SquareCapShader(StrokeShader):
+ def shade(self, stroke):
+ # save the location and attribute of stroke vertices
+ buffer = []
+ for sv in iter_stroke_vertices(stroke):
+ buffer.append((sv.getPoint(), sv.attribute()))
+ # calculate the number of additional vertices to form caps
+ R, L = stroke[0].attribute().getThicknessRL()
+ caplen_beg = (R + L) / 2.0
+ nverts_beg = 1
+ R, L = stroke[-1].attribute().getThicknessRL()
+ caplen_end = (R + L) / 2.0
+ nverts_end = 1
+ # increase the total number of stroke vertices
+ nverts = stroke.strokeVerticesSize()
+ stroke.Resample(nverts + nverts_beg + nverts_end)
+ # restore the location and attribute of the original vertices
+ for i in range(nverts):
+ p, attr = buffer[i]
+ stroke[nverts_beg + i].setPoint(p)
+ stroke[nverts_beg + i].setAttribute(attr)
+ # reshape the cap at the beginning of the stroke
+ q, attr = buffer[1]
+ p, attr = buffer[0]
+ d = p - q
+ stroke[0].setPoint(p + d / d.length * caplen_beg)
+ stroke[0].setAttribute(attr)
+ # reshape the cap at the end of the stroke
+ q, attr = buffer[-2]
+ p, attr = buffer[-1]
+ d = p - q
+ stroke[-1].setPoint(p + d / d.length * caplen_beg)
+ stroke[-1].setAttribute(attr)
+
# main function for parameter processing
def process(layer_name, lineset_name):
@@ -372,7 +466,12 @@ def process(layer_name, lineset_name):
upred = TrueUP1D()
Operators.select(upred)
# join feature edges
- Operators.bidirectionalChain(ChainSilhouetteIterator(), NotUP1D(upred)) # FIXME
+ if linestyle.same_object:
+ bpred = SameShapeIdBP1D()
+ chaining_iterator = ChainPredicateIterator(upred, bpred)
+ else:
+ chaining_iterator = ChainSilhouetteIterator()
+ Operators.bidirectionalChain(chaining_iterator, NotUP1D(upred))
# prepare a list of stroke shaders
color = linestyle.color
shaders_list = [
@@ -422,5 +521,9 @@ def process(layer_name, lineset_name):
shaders_list.append(ThicknessDistanceFromObjectShader(
m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
m.range_min, m.range_max, m.value_min, m.value_max))
+ if linestyle.caps == "ROUND":
+ shaders_list.append(RoundCapShader())
+ elif linestyle.caps == "SQUARE":
+ shaders_list.append(SquareCapShader())
# create strokes using the shaders list
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py
index af59e29c0ca..4ff9a949d99 100644
--- a/release/scripts/ui/properties_render.py
+++ b/release/scripts/ui/properties_render.py
@@ -409,7 +409,11 @@ class RENDER_PT_freestyle_linestyle(RenderButtonsPanel, bpy.types.Panel):
for modifier in linestyle.thickness_modifiers:
self.draw_thickness_modifier(context, modifier)
elif linestyle.panel == "STROKES":
- pass
+ col.label(text="Chaining:")
+ col.prop(linestyle, "same_object")
+ col.label(text="Caps:")
+ sub = col.row(align=True)
+ sub.prop(linestyle, "caps", expand=True)
elif linestyle.panel == "DISTORT":
pass
elif linestyle.panel == "MISC":
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index ef4ce16328f..ba2e150deac 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -62,6 +62,8 @@ static void default_linestyle_settings(FreestyleLineStyle *linestyle)
linestyle->color_modifiers.first = linestyle->color_modifiers.last = NULL;
linestyle->alpha_modifiers.first = linestyle->alpha_modifiers.last = NULL;
linestyle->thickness_modifiers.first = linestyle->thickness_modifiers.last = NULL;
+
+ linestyle->caps = LS_CAPS_BUTT;
}
FreestyleLineStyle *FRS_new_linestyle(char *name, struct Main *main)
diff --git a/source/blender/makesdna/DNA_linestyle_types.h b/source/blender/makesdna/DNA_linestyle_types.h
index a04cbb8c79d..3deef684e3d 100644
--- a/source/blender/makesdna/DNA_linestyle_types.h
+++ b/source/blender/makesdna/DNA_linestyle_types.h
@@ -179,7 +179,13 @@ typedef struct LineStyleThicknessModifier_DistanceFromObject {
#define LS_PANEL_MISC 6
/* FreestyleLineStyle::flag */
-#define LS_DS_EXPAND 1 /* for animation editors */
+#define LS_DS_EXPAND 1 /* for animation editors */
+#define LS_SAME_OBJECT 2
+
+/* FreestyleLineStyle::caps */
+#define LS_CAPS_BUTT 1
+#define LS_CAPS_ROUND 2
+#define LS_CAPS_SQUARE 3
typedef struct FreestyleLineStyle {
ID id;
@@ -187,9 +193,8 @@ typedef struct FreestyleLineStyle {
float r, g, b, alpha;
float thickness;
- int flag;
+ int flag, caps;
int panel; /* for UI */
- int pad1;
ListBase color_modifiers;
ListBase alpha_modifiers;
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index 1aa7b71af2c..9867c1ed9c6 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -400,6 +400,11 @@ static void rna_def_linestyle(BlenderRNA *brna)
{LS_PANEL_DISTORT, "DISTORT", 0, "Distort", "Show the panel for stroke distortion."},
{LS_PANEL_MISC, "MISC", 0, "Misc", "Show the panel for miscellaneous options."},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem cap_items[] = {
+ {LS_CAPS_BUTT, "BUTT", 0, "Butt", "Butt cap (flat)."},
+ {LS_CAPS_ROUND, "ROUND", 0, "Round", "Round cap (half-circle)."},
+ {LS_CAPS_SQUARE, "SQUARE", 0, "Square", "Square cap (flat and extended)."},
+ {0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "FreestyleLineStyle", "ID");
RNA_def_struct_ui_text(srna, "Freestyle Line Style", "Freestyle line style, reusable by multiple line sets");
@@ -444,6 +449,17 @@ static void rna_def_linestyle(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "LineStyleThicknessModifier");
RNA_def_property_ui_text(prop, "Thickness Modifiers", "List of line thickness modifiers.");
+ prop= RNA_def_property(srna, "same_object", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LS_SAME_OBJECT);
+ RNA_def_property_ui_text(prop, "Same Object", "if true, only feature edges of the same object are joined.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "caps", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "caps");
+ RNA_def_property_enum_items(prop, cap_items);
+ RNA_def_property_ui_text(prop, "Cap", "Select the shape of both ends of strokes.");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
}
void RNA_def_linestyle(BlenderRNA *brna)