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/startup/bl_ui/properties_constraint.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py6
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h5
-rw-r--r--source/blender/blenkernel/intern/constraint.c24
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c89
-rw-r--r--source/blender/blenloader/intern/versioning_280.c16
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h3
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h18
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c6
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c29
11 files changed, 169 insertions, 31 deletions
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index 76b87a9011d..c76f3255d97 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -748,6 +748,9 @@ class ConstraintButtonsPanel:
layout.prop(con, "distance")
layout.prop(con, "shrinkwrap_type")
+ if con.shrinkwrap_type in {'PROJECT', 'NEAREST_SURFACE'}:
+ layout.prop(con, 'wrap_mode', text="Snap Mode")
+
if con.shrinkwrap_type == 'PROJECT':
row = layout.row(align=True)
row.prop(con, "project_axis", expand=True)
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 8833db28056..803abe98055 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -825,6 +825,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Mode:")
col.prop(md, "wrap_method", text="")
+ if md.wrap_method in {'PROJECT', 'NEAREST_SURFACEPOINT'}:
+ col.prop(md, "wrap_mode", text="")
+
if md.wrap_method == 'PROJECT':
split = layout.split()
col = split.column()
@@ -851,9 +854,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.prop(md, "auxiliary_target")
- elif md.wrap_method == 'NEAREST_SURFACEPOINT':
- layout.prop(md, "use_keep_above_surface")
-
def SIMPLE_DEFORM(self, layout, ob, md):
layout.row().prop(md, "deform_method", expand=True)
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index d4df12783fa..40f3808b94b 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -94,6 +94,11 @@ bool BKE_shrinkwrap_project_normal(
const struct SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
BVHTree_RayCastCallback callback, void *userdata);
+/* Apply the shrink to surface modes to the given original coordinates and nearest point. */
+void BKE_shrinkwrap_snap_point_to_surface(
+ int mode, const float hit_co[3], const float hit_no[3], float goal_dist,
+ const float point_co[3], float r_point_co[3]);
+
/*
* NULL initializers to local data
*/
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 3ea2f4e0ee4..b1a7c98dc9c 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3456,7 +3456,6 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
case MOD_SHRINKWRAP_NEAREST_VERTEX:
{
BVHTreeNearest nearest;
- float dist;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
@@ -3475,10 +3474,22 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
- dist = len_v3v3(co, nearest.co);
- if (dist != 0.0f) {
- interp_v3_v3v3(co, co, nearest.co, (dist - scon->dist) / dist); /* linear interpolation */
+ if (nearest.index < 0) {
+ fail = true;
+ break;
}
+
+ if (scon->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE) {
+ BKE_shrinkwrap_snap_point_to_surface(scon->shrinkMode, nearest.co, nearest.no, scon->dist, co, co);
+ }
+ else {
+ const float dist = len_v3v3(co, nearest.co);
+
+ if (dist != 0.0f) {
+ interp_v3_v3v3(co, co, nearest.co, (dist - scon->dist) / dist); /* linear interpolation */
+ }
+ }
+
BLI_space_transform_invert(&transform, co);
break;
}
@@ -3522,13 +3533,14 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
break;
}
- if (BKE_shrinkwrap_project_normal(0, co, no, scon->dist, &transform, treeData.tree,
+ if (BKE_shrinkwrap_project_normal(0, co, no, 0.0f, &transform, treeData.tree,
&hit, treeData.raycast_callback, &treeData) == false)
{
fail = true;
break;
}
- copy_v3_v3(co, hit.co);
+
+ BKE_shrinkwrap_snap_point_to_surface(scon->shrinkMode, hit.co, hit.no, scon->dist, co, co);
break;
}
}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index b5888856250..21b21d6ddd8 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -363,7 +363,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(
}
if (hit->index != -1) {
- madd_v3_v3v3fl(hit->co, hit->co, tmp_no, calc->keepDist);
+ BKE_shrinkwrap_snap_point_to_surface(calc->smd->shrinkMode, hit->co, hit->no, calc->keepDist, tmp_co, hit->co);
interp_v3_v3v3(co, co, hit->co, weight);
}
}
@@ -541,26 +541,85 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(
/* Found the nearest vertex */
if (nearest->index != -1) {
- if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) {
- /* Make the vertex stay on the front side of the face */
- madd_v3_v3v3fl(tmp_co, nearest->co, nearest->no, calc->keepDist);
+ BKE_shrinkwrap_snap_point_to_surface(calc->smd->shrinkMode, nearest->co, nearest->no, calc->keepDist, tmp_co, tmp_co);
+
+ /* Convert the coordinates back to mesh coordinates */
+ BLI_space_transform_invert(&calc->local2target, tmp_co);
+ interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
+ }
+}
+
+/* Helper for MOD_SHRINKWRAP_INSIDE, MOD_SHRINKWRAP_OUTSIDE and MOD_SHRINKWRAP_OUTSIDE_SURFACE. */
+static void shrinkwrap_snap_with_side(float r_point_co[3], const float point_co[3], const float hit_co[3], const float hit_no[3], float goal_dist, float forcesign, bool forcesnap)
+{
+ float dist = len_v3v3(point_co, hit_co);
+
+ /* If exactly on the surface, push out along normal */
+ if (dist < FLT_EPSILON) {
+ madd_v3_v3v3fl(r_point_co, hit_co, hit_no, goal_dist * forcesign);
+ }
+ /* Move to the correct side if needed */
+ else {
+ float delta[3];
+ sub_v3_v3v3(delta, point_co, hit_co);
+ float dsign = signf(dot_v3v3(delta, hit_no));
+
+ /* If on the wrong side or too close, move to correct */
+ if (forcesnap || dsign * forcesign < 0 || dist < goal_dist) {
+ interp_v3_v3v3(r_point_co, point_co, hit_co, (dist - goal_dist * dsign * forcesign) / dist);
}
else {
- /* Adjusting the vertex weight,
- * so that after interpolating it keeps a certain distance from the nearest position */
- const float dist = sasqrt(nearest->dist_sq);
- if (dist > FLT_EPSILON) {
- /* linear interpolation */
- interp_v3_v3v3(tmp_co, tmp_co, nearest->co, (dist - calc->keepDist) / dist);
+ copy_v3_v3(r_point_co, point_co);
+ }
+ }
+}
+
+/**
+ * Apply the shrink to surface modes to the given original coordinates and nearest point.
+ * r_point_co may be the same memory location as point_co, hit_co, or hit_no.
+ */
+void BKE_shrinkwrap_snap_point_to_surface(
+ int mode, const float hit_co[3], const float hit_no[3], float goal_dist,
+ const float point_co[3], float r_point_co[3])
+{
+ float dist;
+
+ switch (mode) {
+ /* Offsets along the line between point_co and hit_co. */
+ case MOD_SHRINKWRAP_ON_SURFACE:
+ if (goal_dist > 0 && (dist = len_v3v3(point_co, hit_co)) > FLT_EPSILON) {
+ interp_v3_v3v3(r_point_co, point_co, hit_co, (dist - goal_dist) / dist);
}
else {
- copy_v3_v3(tmp_co, nearest->co);
+ copy_v3_v3(r_point_co, hit_co);
}
- }
+ break;
- /* Convert the coordinates back to mesh coordinates */
- BLI_space_transform_invert(&calc->local2target, tmp_co);
- interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
+ case MOD_SHRINKWRAP_INSIDE:
+ shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, -1, false);
+ break;
+
+ case MOD_SHRINKWRAP_OUTSIDE:
+ shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, +1, false);
+ break;
+
+ case MOD_SHRINKWRAP_OUTSIDE_SURFACE:
+ if (goal_dist > 0) {
+ shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, +1, true);
+ }
+ else {
+ copy_v3_v3(r_point_co, hit_co);
+ }
+ break;
+
+ /* Offsets along the normal */
+ case MOD_SHRINKWRAP_ABOVE_SURFACE:
+ madd_v3_v3v3fl(r_point_co, hit_co, hit_no, goal_dist);
+ break;
+
+ default:
+ printf("Unknown Shrinkwrap surface snap mode: %d\n", mode);
+ copy_v3_v3(r_point_co, hit_co);
}
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 6b74e4f2239..4ec283c35ca 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -2074,4 +2074,20 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ {
+ if (!DNA_struct_elem_find(fd->filesdna, "ShrinkwrapModifierData", "char", "shrinkMode")) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Shrinkwrap) {
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*)md;
+ if (smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) {
+ smd->shrinkMode = MOD_SHRINKWRAP_ABOVE_SURFACE;
+ smd->shrinkOpts &= ~MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE;
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 4f3f3891240..e7d9e1fa7dd 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -428,7 +428,8 @@ typedef struct bShrinkwrapConstraint {
char projAxis; /* axis to project/constrain */
char projAxisSpace; /* space to project axis in */
float projLimit; /* distance to search */
- char pad[4];
+ char shrinkMode; /* inside/outside/on surface (see MOD shrinkwrap) */
+ char pad[3];
} bShrinkwrapConstraint;
/* Follow Track constraints */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 247b08475a1..811373e626c 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -870,7 +870,7 @@ typedef struct ShrinkwrapModifierData {
float keepDist; /* distance offset to keep from mesh/projection point */
short shrinkType; /* shrink type projection */
char shrinkOpts; /* shrink options */
- char pad1;
+ char shrinkMode; /* shrink to surface mode */
float projLimit; /* limit the projection ray cast */
char projAxis; /* axis to project over */
@@ -889,6 +889,20 @@ enum {
MOD_SHRINKWRAP_NEAREST_VERTEX = 2,
};
+/* Shrinkwrap->shrinkMode */
+enum {
+ /* Move vertex to the surface of the target object (keepDist towards original position) */
+ MOD_SHRINKWRAP_ON_SURFACE = 0,
+ /* Move the vertex inside the target object; don't change if already inside */
+ MOD_SHRINKWRAP_INSIDE = 1,
+ /* Move the vertex outside the target object; don't change if already outside */
+ MOD_SHRINKWRAP_OUTSIDE = 2,
+ /* Move vertex to the surface of the target object, with keepDist towards the outside */
+ MOD_SHRINKWRAP_OUTSIDE_SURFACE = 3,
+ /* Move vertex to the surface of the target object, with keepDist along the normal */
+ MOD_SHRINKWRAP_ABOVE_SURFACE = 4,
+};
+
/* Shrinkwrap->shrinkOpts */
enum {
/* allow shrinkwrap to move the vertex in the positive direction of axis */
@@ -901,7 +915,9 @@ enum {
/* ignore vertex moves if a vertex ends projected on a back face of the target */
MOD_SHRINKWRAP_CULL_TARGET_BACKFACE = (1 << 4),
+#ifdef DNA_DEPRECATED_ALLOW
MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE = (1 << 5), /* distance is measure to the front face of the target */
+#endif
MOD_SHRINKWRAP_INVERT_VGROUP = (1 << 6),
};
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 56b82c6c2f9..935af5c8bbd 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -72,6 +72,7 @@ extern const EnumPropertyItem rna_enum_object_shaderfx_type_items[];
extern const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[];
extern const EnumPropertyItem rna_enum_modifier_triangulate_ngon_method_items[];
+extern const EnumPropertyItem rna_enum_modifier_shrinkwrap_mode_items[];
extern const EnumPropertyItem rna_enum_image_type_items[];
extern const EnumPropertyItem rna_enum_image_color_mode_items[];
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 52c6bc105fd..39966983a8a 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1934,6 +1934,12 @@ static void rna_def_constraint_shrinkwrap(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shrinkwrap Type", "Select type of shrinkwrap algorithm for target position");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ prop = RNA_def_property(srna, "wrap_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "shrinkMode");
+ RNA_def_property_enum_items(prop, rna_enum_modifier_shrinkwrap_mode_items);
+ RNA_def_property_ui_text(prop, "Snap Mode", "Select how to constrain the object to the target surface");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 2b0f22eb8fc..1755a37016a 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -140,6 +140,24 @@ const EnumPropertyItem rna_enum_modifier_triangulate_ngon_method_items[] = {
{0, NULL, 0, NULL, NULL}
};
+const EnumPropertyItem rna_enum_modifier_shrinkwrap_mode_items[] = {
+ {MOD_SHRINKWRAP_ON_SURFACE, "ON_SURFACE", 0, "On Surface",
+ "The point is constrained to the surface of the target object, "
+ "with distance offset towards the original point location"},
+ {MOD_SHRINKWRAP_INSIDE, "INSIDE", 0, "Inside",
+ "The point is constrained to be inside the target object"},
+ {MOD_SHRINKWRAP_OUTSIDE, "OUTSIDE", 0, "Outside",
+ "The point is constrained to be outside the target object"},
+ {MOD_SHRINKWRAP_OUTSIDE_SURFACE, "OUTSIDE_SURFACE", 0, "Outside Surface",
+ "The point is constrained to the surface of the target object, "
+ "with distance offset always to the outside, towards or away from the original location"},
+ {MOD_SHRINKWRAP_ABOVE_SURFACE, "ABOVE_SURFACE", 0, "Above Surface",
+ "The point is constrained to the surface of the target object, "
+ "with distance offset applied exactly along the target normal"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+
#ifndef RNA_RUNTIME
/* use eWarp_Falloff_*** & eHook_Falloff_***, they're in sync */
static const EnumPropertyItem modifier_warp_falloff_items[] = {
@@ -3173,6 +3191,12 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "wrap_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "shrinkMode");
+ RNA_def_property_enum_items(prop, rna_enum_modifier_shrinkwrap_mode_items);
+ RNA_def_property_ui_text(prop, "Snap Mode", "Select how vertices are constrained to the target surface");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "cull_face", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrinkOpts");
RNA_def_property_enum_items(prop, shrink_face_cull_items);
@@ -3249,11 +3273,6 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Positive", "Allow vertices to move in the positive direction of axis");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "use_keep_above_surface", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE);
- RNA_def_property_ui_text(prop, "Keep Above Surface", "");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_INVERT_VGROUP);
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");