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 /source/blender/freestyle/intern/blender_interface
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.
Diffstat (limited to 'source/blender/freestyle/intern/blender_interface')
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp111
1 files changed, 99 insertions, 12 deletions
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++;