[Bf-blender-cvs] [b36044c4004] shrinkwrap-features: Implement additional modes for Shrinkrwap to Nearest Surface Point.

Alexander Gavrilov noreply at git.blender.org
Sat Jul 7 22:21:26 CEST 2018


Commit: b36044c400412c5ead78f18d008128472f53fa41
Author: Alexander Gavrilov
Date:   Sat Jul 7 18:39:45 2018 +0300
Branches: shrinkwrap-features
https://developer.blender.org/rBb36044c400412c5ead78f18d008128472f53fa41

Implement additional modes for Shrinkrwap to Nearest Surface Point.

In addition to the original map to surface and Keep Above Surface,
add modes that only affect vertices that are inside or outside
the object. This is inspired by the Limit Distance constraint.

===================================================================

M	release/scripts/startup/bl_ui/properties_constraint.py
M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/BKE_shrinkwrap.h
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/blenkernel/intern/shrinkwrap.c
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/makesdna/DNA_constraint_types.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_constraint.c
M	source/blender/makesrna/intern/rna_modifier.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index b7880e605b3..64c988b5895 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -753,6 +753,9 @@ class ConstraintButtonsPanel:
             rowsub.prop(con, "project_axis_space", text="")
             layout.prop(con, "project_limit")
 
+        elif con.shrinkwrap_type == 'NEAREST_SURFACE':
+            layout.prop(con, 'surface_wrap_mode', text="Surface Mode")
+
     def DAMPED_TRACK(self, context, layout, con):
         self.target_template(layout, con)
 
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index a147950a36d..44f00c0c70e 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -834,7 +834,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
             layout.prop(md, "auxiliary_target")
 
         elif md.wrap_method == 'NEAREST_SURFACEPOINT':
-            layout.prop(md, "use_keep_above_surface")
+            col.prop(md, "surface_wrap_mode", text="")
 
     def SIMPLE_DEFORM(self, layout, ob, md):
 
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 31b4b5cecc5..e22edb64bd5 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);
 
+/*
+ * This function applies the shrink to surface modes to the given original coordinates and nearest point.
+ */
+void BKE_shrinkwrap_snap_coord_to_surface(float tmp_co[3], BVHTreeNearest *nearest, float goal_dist, int mode);
+
 /*
  * NULL initializers to local data
  */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 2a5a0cf9ae7..0c12ef4acb3 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3502,7 +3502,6 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
 				case MOD_SHRINKWRAP_NEAREST_VERTEX:
 				{
 					BVHTreeNearest nearest;
-					float dist;
 
 					nearest.index = -1;
 					nearest.dist_sq = FLT_MAX;
@@ -3521,10 +3520,22 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
 
 					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_coord_to_surface(co, &nearest, scon->dist, scon->shrinkMode);
 					}
+					else {
+						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;
 				}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index e28b4ccc23d..cbb82b2aea7 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -557,26 +557,61 @@ 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) {
+		BKE_shrinkwrap_snap_coord_to_surface(tmp_co, nearest, calc->keepDist, calc->smd->shrinkMode);
+
+		/* 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 */
+	}
+}
+
+void BKE_shrinkwrap_snap_coord_to_surface(float tmp_co[3], BVHTreeNearest *nearest, float goal_dist, int mode)
+{
+	/* Adjusting the vertex weight,
+	 * so that after interpolating it keeps a certain distance from the nearest position */
+	const float dist = sasqrt(nearest->dist_sq);
+	float forcesign = 0.0f;
+	bool forcesnap = false;
+
+	switch (mode) {
+		case MOD_SHRINKWRAP_ON_SURFACE:
+			break;
+		case MOD_SHRINKWRAP_INSIDE:
+			forcesign = -1.0f;
+			break;
+		case MOD_SHRINKWRAP_OUTSIDE:
+			forcesign = 1.0f;
+			break;
+		case MOD_SHRINKWRAP_ABOVE_SURFACE:
 			/* Make the vertex stay on the front side of the face */
-			madd_v3_v3v3fl(tmp_co, nearest->co, nearest->no, calc->keepDist);
+			forcesign = 1.0f;
+			forcesnap = true;
+			break;
+	}
+
+	if (forcesign != 0.0f) {
+		/* If exactly on the surface, push out along normal */
+		if (dist < FLT_EPSILON) {
+			madd_v3_v3v3fl(tmp_co, nearest->co, nearest->no, goal_dist * forcesign);
 		}
+		/* Move to the correct side if needed */
 		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);
-			}
-			else {
-				copy_v3_v3(tmp_co, nearest->co);
+			float delta[3];
+			sub_v3_v3v3(delta, tmp_co, nearest->co);
+			float dsign = signf(dot_v3v3(delta, nearest->no));
+
+			/* If on the wrong side or too close, move to correct */
+			if (forcesnap || dsign * forcesign < 0 || dist < goal_dist) {
+				interp_v3_v3v3(tmp_co, tmp_co, nearest->co, (dist - goal_dist * dsign * forcesign) / dist);
 			}
 		}
-
-		/* 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 */
+	}
+	else if (dist > FLT_EPSILON) {
+		/* linear interpolation */
+		interp_v3_v3v3(tmp_co, tmp_co, nearest->co, (dist - goal_dist) / dist);
+	}
+	else {
+		copy_v3_v3(tmp_co, nearest->co);
 	}
 }
 
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 20f2a747fb2..9b4c394d548 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1826,6 +1826,18 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
 			}
 		}
 	}
+
+	{
+		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;
+				}
+			}
+		}
+	}
 }
 
 void do_versions_after_linking_270(Main *bmain)
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 2ae686d178e..f160d0a971c 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 00ae9ff8b60..e70b3ad400a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -816,7 +816,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 */
 
@@ -835,6 +835,14 @@ enum {
 	MOD_SHRINKWRAP_NEAREST_VERTEX  = 2,
 };
 
+/* Shrinkwrap->shrinkMode */
+enum {
+	MOD_SHRINKWRAP_ON_SURFACE      = 0,
+	MOD_SHRINKWRAP_INSIDE          = 1,
+	MOD_SHRINKWRAP_OUTSIDE         = 2,
+	MOD_SHRINKWRAP_ABOVE_SURFACE   = 3,
+};
+
 /* Shrinkwrap->shrinkOpts */
 enum {
 	/* allow shrinkwrap to move the vertex in the positive direction of axis */
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 4b563bf6659..6e9cf1fd5dd 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -2081,6 +2081,19 @@ static void rna_def_constraint_shrinkwrap(BlenderRNA *brna)
 		{0, NULL, 0, NULL, NULL}
 	};
 
+	static const EnumPropertyItem mode_items[] = {
+		{MOD_SHRINKWRAP_ON_SURFACE, "ON_SURFACE", 0, "On Surface",
+		                            "The object is constrained to the surface of the target object"},
+		{MOD_SHRINKWRAP_INSIDE, "INSIDE", 0, "Inside",
+		                        "The object is constrained to be inside the target object"},
+		{MOD_SHRINKWRAP_OUTSIDE, "OUTSIDE", 0, "Outside",
+		                         "The object is constrained to be outside the target object"},
+		{MOD_SHRINKWRAP_ABOVE_SURFACE, "ABOVE_SURFACE", 0, "Above Surface",
+		                               "The object is constrained to the outer surface of the target object, "
+		                               "i.e. the distance offset is always along the normal."},
+		{0, NULL, 0, NULL, NULL}
+	};
+
 	srna = RNA_def_struct(brna, "ShrinkwrapConstraint", "Constraint");
 	RNA_def_struct_ui_text(srna, "Shrinkwrap Constraint", "Create constraint-based shrinkwrap relationship");
 	RNA_def_struct_sdna_from(srna, "bShrinkwrapConstrai

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list