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.py69
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py32
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp111
-rw-r--r--source/blender/makesdna/DNA_freestyle_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_scene.c60
5 files changed, 213 insertions, 64 deletions
diff --git a/release/scripts/freestyle/style_modules/parameter_editor.py b/release/scripts/freestyle/style_modules/parameter_editor.py
index 0c4987aabb8..dc98b968acf 100644
--- a/release/scripts/freestyle/style_modules/parameter_editor.py
+++ b/release/scripts/freestyle/style_modules/parameter_editor.py
@@ -505,7 +505,7 @@ class QuantitativeInvisibilityRangeUP1D(UnaryPredicate1D):
def join_unary_predicates(upred_list, bpred):
if not upred_list:
- return TrueUP1D()
+ return None
upred = upred_list[0]
for p in upred_list[1:]:
upred = bpred(upred, p)
@@ -835,47 +835,36 @@ def process(layer_name, lineset_name):
# prepare selection criteria by edge types
if lineset.select_by_edge_types:
edge_type_criteria = []
- if lineset.edge_type_combination == "OR":
- flags = Nature.NO_FEATURE
- if lineset.select_silhouette:
- flags |= Nature.SILHOUETTE
- if lineset.select_border:
- flags |= Nature.BORDER
- if lineset.select_crease:
- flags |= Nature.CREASE
- if lineset.select_ridge:
- flags |= Nature.RIDGE
- if lineset.select_valley:
- flags |= Nature.VALLEY
- if lineset.select_suggestive_contour:
- flags |= Nature.SUGGESTIVE_CONTOUR
- if lineset.select_material_boundary:
- flags |= Nature.MATERIAL_BOUNDARY
- if lineset.select_edge_mark:
- flags |= Nature.EDGE_MARK
- if flags != Nature.NO_FEATURE:
- edge_type_criteria.append(pyNatureUP1D(flags))
- else:
- if lineset.select_silhouette:
- edge_type_criteria.append(pyNatureUP1D(Nature.SILHOUETTE))
- if lineset.select_border:
- edge_type_criteria.append(pyNatureUP1D(Nature.BORDER))
- if lineset.select_crease:
- edge_type_criteria.append(pyNatureUP1D(Nature.CREASE))
- if lineset.select_ridge:
- edge_type_criteria.append(pyNatureUP1D(Nature.RIDGE))
- if lineset.select_valley:
- edge_type_criteria.append(pyNatureUP1D(Nature.VALLEY))
- if lineset.select_suggestive_contour:
- edge_type_criteria.append(pyNatureUP1D(Nature.SUGGESTIVE_CONTOUR))
- if lineset.select_material_boundary:
- edge_type_criteria.append(pyNatureUP1D(Nature.MATERIAL_BOUNDARY))
- if lineset.select_edge_mark:
- edge_type_criteria.append(pyNatureUP1D(Nature.EDGE_MARK))
+ if lineset.select_silhouette:
+ upred = pyNatureUP1D(Nature.SILHOUETTE)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_silhouette else upred)
+ if lineset.select_border:
+ upred = pyNatureUP1D(Nature.BORDER)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_border else upred)
+ if lineset.select_crease:
+ upred = pyNatureUP1D(Nature.CREASE)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_crease else upred)
+ if lineset.select_ridge:
+ upred = pyNatureUP1D(Nature.RIDGE)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_ridge else upred)
+ if lineset.select_valley:
+ upred = pyNatureUP1D(Nature.VALLEY)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_valley else upred)
+ if lineset.select_suggestive_contour:
+ upred = pyNatureUP1D(Nature.SUGGESTIVE_CONTOUR)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_suggestive_contour else upred)
+ if lineset.select_material_boundary:
+ upred = pyNatureUP1D(Nature.MATERIAL_BOUNDARY)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_material_boundary else upred)
+ if lineset.select_edge_mark:
+ upred = pyNatureUP1D(Nature.EDGE_MARK)
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_edge_mark else upred)
if lineset.select_contour:
- edge_type_criteria.append(ContourUP1D())
+ upred = ContourUP1D()
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_contour else upred)
if lineset.select_external_contour:
- edge_type_criteria.append(ExternalContourUP1D())
+ upred = ExternalContourUP1D()
+ edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_external_contour else upred)
if lineset.edge_type_combination == "OR":
upred = join_unary_predicates(edge_type_criteria, OrUP1D)
else:
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 04d3ecb120f..e7aca0c9930 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -261,6 +261,17 @@ class RENDER_PT_freestyle_lineset(RenderButtonsPanel, Panel):
return freestyle.mode == "EDITOR" and freestyle.linesets.active
return False
+ def draw_edge_type_buttons(self, box, lineset, edge_type):
+ # property names
+ select_edge_type = "select_" + edge_type
+ exclude_edge_type = "exclude_" + edge_type
+ # draw edge type buttons
+ row = box.row(align=True)
+ row.prop(lineset, select_edge_type)
+ sub = row.column()
+ sub.prop(lineset, exclude_edge_type, text="")
+ sub.enabled = getattr(lineset, select_edge_type)
+
def draw(self, context):
layout = self.layout
@@ -293,17 +304,18 @@ class RENDER_PT_freestyle_lineset(RenderButtonsPanel, Panel):
row = col.row()
sub = row.column()
- sub.prop(lineset, "select_silhouette")
- sub.prop(lineset, "select_border")
- sub.prop(lineset, "select_crease")
- sub.prop(lineset, "select_ridge")
- sub.prop(lineset, "select_valley")
- sub.prop(lineset, "select_suggestive_contour")
- sub.prop(lineset, "select_material_boundary")
- sub.prop(lineset, "select_edge_mark")
+ self.draw_edge_type_buttons(sub, lineset, "silhouette")
+ self.draw_edge_type_buttons(sub, lineset, "border")
+
+ self.draw_edge_type_buttons(sub, lineset, "crease")
+ self.draw_edge_type_buttons(sub, lineset, "ridge")
+ self.draw_edge_type_buttons(sub, lineset, "valley")
+ self.draw_edge_type_buttons(sub, lineset, "suggestive_contour")
+ self.draw_edge_type_buttons(sub, lineset, "material_boundary")
+ self.draw_edge_type_buttons(sub, lineset, "edge_mark")
sub = row.column()
- sub.prop(lineset, "select_contour")
- sub.prop(lineset, "select_external_contour")
+ self.draw_edge_type_buttons(sub, lineset, "contour")
+ self.draw_edge_type_buttons(sub, lineset, "external_contour")
col.separator() # XXX
col.prop(lineset, "select_by_face_marks")
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index ec3bd9f5c5b..ab1d9e371e7 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -160,6 +160,69 @@ extern "C" {
return text;
}
+ struct edge_type_condition {
+ int edge_type, value;
+ };
+
+ // examines the conditions and returns true if the target edge type needs to be computed
+ static bool test_edge_type_conditions(struct edge_type_condition *conditions,
+ int num_edge_types, bool logical_and, int target, bool distinct)
+ {
+ int target_condition = 0;
+ int num_non_target_positive_conditions = 0;
+ int num_non_target_negative_conditions = 0;
+
+ for (int i = 0; i < num_edge_types; i++) {
+ if (conditions[i].edge_type == target)
+ target_condition = conditions[i].value;
+ else if (conditions[i].value > 0)
+ ++num_non_target_positive_conditions;
+ else if (conditions[i].value < 0)
+ ++num_non_target_negative_conditions;
+ }
+ if (distinct) {
+ // In this case, the 'target' edge type is assumed to appear on distinct edge
+ // of its own and never together with other edge types.
+ if (logical_and) {
+ if (num_non_target_positive_conditions > 0)
+ return false;
+ if (target_condition > 0)
+ return true;
+ if (target_condition < 0)
+ return false;
+ if (num_non_target_negative_conditions > 0)
+ return true;
+ } else {
+ if (target_condition > 0)
+ return true;
+ if (num_non_target_negative_conditions > 0)
+ return true;
+ if (target_condition < 0)
+ return false;
+ if (num_non_target_positive_conditions > 0)
+ return false;
+ }
+ } else {
+ // In this case, the 'target' edge type may appear together with other edge types.
+ if (target_condition > 0)
+ return true;
+ if (target_condition < 0)
+ return true;
+ if (logical_and) {
+ if (num_non_target_positive_conditions > 0)
+ return false;
+ if (num_non_target_negative_conditions > 0)
+ return true;
+ } else {
+ if (num_non_target_negative_conditions > 0)
+ return true;
+ if (num_non_target_positive_conditions > 0)
+ return false;
+ }
+ }
+ return true;
+ }
+
static void prepare(Render* re, SceneRenderLayer* srl ) {
// load mesh
@@ -197,6 +260,18 @@ extern "C" {
int use_ridges_and_valleys = 0;
int use_suggestive_contours = 0;
int use_material_boundaries = 0;
+ struct edge_type_condition conditions[] = {
+ {FREESTYLE_FE_SILHOUETTE, 0},
+ {FREESTYLE_FE_BORDER, 0},
+ {FREESTYLE_FE_CREASE, 0},
+ {FREESTYLE_FE_RIDGE, 0},
+ {FREESTYLE_FE_VALLEY, 0},
+ {FREESTYLE_FE_SUGGESTIVE_CONTOUR, 0},
+ {FREESTYLE_FE_MATERIAL_BOUNDARY, 0},
+ {FREESTYLE_FE_CONTOUR, 0},
+ {FREESTYLE_FE_EXTERNAL_CONTOUR, 0},
+ {FREESTYLE_FE_EDGE_MARK, 0}};
+ int num_edge_types = sizeof(conditions) / sizeof(struct edge_type_condition);
cout << "Linesets:"<< endl;
for (FreestyleLineSet *lineset = (FreestyleLineSet *)config->linesets.first; lineset; lineset = lineset->next) {
if (lineset->flags & FREESTYLE_LINESET_ENABLED) {
@@ -208,21 +283,33 @@ extern "C" {
++use_ridges_and_valleys;
++use_suggestive_contours;
++use_material_boundaries;
- } else if (lineset->flags & FREESTYLE_LINESET_FE_NOT) {
- if (!(lineset->edge_types & ~FREESTYLE_FE_RIDGE) ||
- !(lineset->edge_types & ~FREESTYLE_FE_VALLEY) ||
- (lineset->flags & FREESTYLE_LINESET_FE_AND))
- ++use_ridges_and_valleys;
- if (lineset->edge_types & ~FREESTYLE_FE_SUGGESTIVE_CONTOUR)
- ++use_suggestive_contours;
- if (lineset->edge_types & ~FREESTYLE_FE_MATERIAL_BOUNDARY)
- ++use_material_boundaries;
} else {
- if (lineset->edge_types & (FREESTYLE_FE_RIDGE | FREESTYLE_FE_VALLEY))
+ // conditions for feature edge selection by edge types
+ for (int i = 0; i < num_edge_types; i++) {
+ if (!(lineset->edge_types & conditions[i].edge_type))
+ conditions[i].value = 0; // no condition specified
+ else if (!(lineset->exclude_edge_types & conditions[i].edge_type))
+ conditions[i].value = 1; // condition: X
+ else
+ conditions[i].value = -1; // condition: NOT X
+ }
+ // logical operator for the selection conditions
+ bool logical_and = ((lineset->flags & FREESTYLE_LINESET_FE_AND) != 0);
+ // negation operator
+ if (lineset->flags & FREESTYLE_LINESET_FE_NOT) {
+ // convert an Exclusive condition into an Inclusive equivalent using De Morgan's laws:
+ // NOT (X OR Y) --> (NOT X) AND (NOT Y)
+ // NOT (X AND Y) --> (NOT X) OR (NOT Y)
+ for (int i = 0; i < num_edge_types; i++)
+ conditions[i].value *= -1;
+ logical_and = !logical_and;
+ }
+ if (test_edge_type_conditions(conditions, num_edge_types, logical_and, FREESTYLE_FE_RIDGE, true) ||
+ test_edge_type_conditions(conditions, num_edge_types, logical_and, FREESTYLE_FE_VALLEY, true))
++use_ridges_and_valleys;
- if (lineset->edge_types & FREESTYLE_FE_SUGGESTIVE_CONTOUR)
+ if (test_edge_type_conditions(conditions, num_edge_types, logical_and, FREESTYLE_FE_SUGGESTIVE_CONTOUR, true))
++use_suggestive_contours;
- if (lineset->edge_types & FREESTYLE_FE_MATERIAL_BOUNDARY)
+ if (test_edge_type_conditions(conditions, num_edge_types, logical_and, FREESTYLE_FE_MATERIAL_BOUNDARY, true))
++use_material_boundaries;
}
layer_count++;
diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h
index 08b4f406223..30888bff15f 100644
--- a/source/blender/makesdna/DNA_freestyle_types.h
+++ b/source/blender/makesdna/DNA_freestyle_types.h
@@ -61,7 +61,7 @@ struct FreestyleLineStyle;
#define FREESTYLE_SEL_IMAGE_BORDER 8
#define FREESTYLE_SEL_FACE_MARK 16
-/* FreestyleLineSet::fedge_types */
+/* FreestyleLineSet::edge_types, exclude_edge_types */
#define FREESTYLE_FE_SILHOUETTE 1
#define FREESTYLE_FE_BORDER 2
#define FREESTYLE_FE_CREASE 4
@@ -98,7 +98,8 @@ typedef struct FreestyleLineSet {
short qi; /* quantitative invisibility */
short pad1;
int qi_start, qi_end;
- int edge_types; /* feature edge types */
+ int edge_types, exclude_edge_types; /* feature edge types */
+ int pad2;
struct Group *group; /* group of target objects */
struct FreestyleLineStyle *linestyle;
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index b505b4b80fa..8cee0987c2e 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1969,6 +1969,66 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Edge Mark", "Select edge marks.");
RNA_def_property_update(prop, NC_SCENE, NULL);
+ prop= RNA_def_property(srna, "exclude_silhouette", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_SILHOUETTE);
+ RNA_def_property_ui_text(prop, "Silhouette", "Exclude silhouette edges.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_border", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_BORDER);
+ RNA_def_property_ui_text(prop, "Border", "Exclude border edges.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_crease", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_CREASE);
+ RNA_def_property_ui_text(prop, "Crease", "Exclude crease edges.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_ridge", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_RIDGE);
+ RNA_def_property_ui_text(prop, "Ridge", "Exclude ridges.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_valley", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_VALLEY);
+ RNA_def_property_ui_text(prop, "Valley", "Exclude valleys.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_suggestive_contour", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_SUGGESTIVE_CONTOUR);
+ RNA_def_property_ui_text(prop, "Suggestive Contour", "Exclude suggestive contours.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_material_boundary", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_MATERIAL_BOUNDARY);
+ RNA_def_property_ui_text(prop, "Material Boundary", "Exclude edges at material boundaries.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_contour", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_CONTOUR);
+ RNA_def_property_ui_text(prop, "Contour", "Exclude contours.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_external_contour", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_EXTERNAL_CONTOUR);
+ RNA_def_property_ui_text(prop, "External Contour", "Exclude external contours.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exclude_edge_mark", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_EDGE_MARK);
+ RNA_def_property_ui_text(prop, "Edge Mark", "Exclude edge marks.");
+ RNA_def_property_ui_icon(prop, ICON_X, 0);
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
prop= RNA_def_property(srna, "visibility", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "qi");
RNA_def_property_enum_items(prop, visibility_items);