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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2011-10-28 00:57:14 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2011-10-28 00:57:14 +0400
commitf0ca79bccb5e8290d02318b81aebdeb713180886 (patch)
tree06be5836fdcce2e69355326e7e6ce5985c3956f9
parent510c69368b7382aa55f3fae0dac9ee6aaadee7e5 (diff)
Extended the set of conditions for feature edge selection by edge types.
In the Parameter Editor mode, each edge type check button in the Selection by Edge Types has now an associated toggle button to exclude the edge type from the feature edge selection. This allows you to select, for instance, those edges that are silhouette lines but not external contours.
-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);