Commit: e5b18390fa591c8b37b9ef9884611b2888bab188
Author: Alexander Gavrilov
Date:   Wed Oct 3 19:09:43 2018 +0300
Branches: blender2.8
https://developer.blender.org/rBe5b18390fa591c8b37b9ef9884611b2888bab188

Shrinkwrap: implement the use of smooth normals in constraint & modifier.

- Use smooth normals to displace in Above Surface mode.
- Add an option to align an axis to the normal in the constraint.

I've seen people request the alignment feature, and it seems useful.
For the actual aligning I use the damped track logic.

In order to conveniently keep mesh data needed for normal
computation together, a new data structure is introduced.

Reviewers: mont29

Differential Revision: https://developer.blender.org/D3762

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

M       release/scripts/startup/bl_ui/properties_constraint.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/depsgraph/intern/builder/deg_builder_relations.cc
M       source/blender/makesdna/DNA_constraint_types.h
M       source/blender/makesrna/intern/rna_constraint.c
M       source/blender/makesrna/intern/rna_modifier.c
M       source/blender/modifiers/intern/MOD_shrinkwrap.c

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

diff --git a/release/scripts/startup/bl_ui/properties_constraint.py 
b/release/scripts/startup/bl_ui/properties_constraint.py
index ea3b5f000ec..4be1f55b3b8 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -769,6 +769,13 @@ class ConstraintButtonsPanel:
             rowsub.prop(con, "use_invert_cull")
             layout.prop(con, "project_limit")
 
+        if con.shrinkwrap_type in ['PROJECT', 'NEAREST_SURFACE']:
+            layout.prop(con, "use_track_normal")
+
+            row = layout.row(align=True)
+            row.active = con.use_track_normal
+            row.prop(con, "track_axis", expand=True)
+
     def DAMPED_TRACK(self, context, layout, con):
         self.target_template(layout, con)
 
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h 
b/source/blender/blenkernel/BKE_shrinkwrap.h
index 40f3808b94b..d1a14003b04 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -55,27 +55,25 @@ struct ShrinkwrapModifierData;
 struct BVHTree;
 struct SpaceTransform;
 
+typedef struct ShrinkwrapTreeData {
+       Mesh *mesh;
 
-typedef struct ShrinkwrapCalcData {
-       ShrinkwrapModifierData *smd;    //shrinkwrap modifier data
+       BVHTree *bvh;
+       BVHTreeFromMesh treeData;
 
-       struct Object *ob;              //object we are applying shrinkwrap to
+       float (*clnors)[3];
+} ShrinkwrapTreeData;
 
-       struct MVert *vert;             //Array of verts being projected (to 
fetch normals or other data)
-       float (*vertexCos)[3];          //vertexs being shrinkwraped
-       int numVerts;
+/* Checks if the modifier needs target normals with these settings. */
+bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode);
 
-       struct MDeformVert *dvert;      //Pointer to mdeform array
-       int vgroup;                     //Vertex group num
-       bool invert_vgroup;             /* invert vertex group influence */
+/* Initializes the mesh data structure from the given mesh and settings. */
+bool BKE_shrinkwrap_init_tree(struct ShrinkwrapTreeData *data, Mesh *mesh, int 
shrinkType, int shrinkMode, bool force_normals);
 
-       struct Mesh *target;     //mesh we are shrinking to
-       struct SpaceTransform local2target;    //transform to move between 
local and target space
-
-       float keepDist;                 //Distance to keep above target surface 
(units are in local space)
-
-} ShrinkwrapCalcData;
+/* Frees the tree data if necessary. */
+void BKE_shrinkwrap_free_tree(struct ShrinkwrapTreeData *data);
 
+/* Implementation of the Shrinkwrap modifier */
 void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct 
Scene *scene, struct Object *ob, struct Mesh *mesh,
                                float (*vertexCos)[3], int numVerts);
 
@@ -91,12 +89,17 @@ void shrinkwrapModifier_deform(struct 
ShrinkwrapModifierData *smd, struct Scene
  */
 bool BKE_shrinkwrap_project_normal(
         char options, const float vert[3], const float dir[3], const float 
ray_radius,
-        const struct SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
-        BVHTree_RayCastCallback callback, void *userdata);
+        const struct SpaceTransform *transf, struct ShrinkwrapTreeData *tree, 
BVHTreeRayHit *hit);
+
+/* Computes a smooth normal of the target (if applicable) at the hit location. 
*/
+void BKE_shrinkwrap_compute_smooth_normal(
+        const struct ShrinkwrapTreeData *tree, const struct SpaceTransform 
*transform,
+        int looptri_idx, const float hit_co[3], const float hit_no[3], float 
r_no[3]);
 
 /* 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 struct ShrinkwrapTreeData *tree, const struct SpaceTransform 
*transform,
+        int mode, int hit_idx, const float hit_co[3], const float hit_no[3], 
float goal_dist,
         const float point_co[3], float r_point_co[3]);
 
 /*
diff --git a/source/blender/blenkernel/intern/constraint.c 
b/source/blender/blenkernel/intern/constraint.c
index 8e85cc39321..f343a62eaf7 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -107,6 +107,8 @@
  * type-info structs.
  */
 
+static void damptrack_do_transform(float matrix[4][4], const float tarvec[3], 
int track_axis);
+
 /* -------------- Naming -------------- */
 
 /* Find the first available, non-duplicate name for a given constraint */
@@ -3417,15 +3419,18 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
 
                bool fail = false;
                float co[3] = {0.0f, 0.0f, 0.0f};
+               bool track_normal = false;
+               float track_no[3] = {0.0f, 0.0f, 0.0f};
 
                SpaceTransform transform;
                Mesh *target_eval = mesh_get_eval_final(depsgraph, 
DEG_get_input_scene(depsgraph), ct->tar, CD_MASK_BAREMESH);
 
-               BVHTreeFromMesh treeData = {NULL};
+               copy_m4_m4(ct->matrix, cob->matrix);
 
-               unit_m4(ct->matrix);
+               bool do_track_normal = (scon->flag & 
CON_SHRINKWRAP_TRACK_NORMAL) != 0;
+               ShrinkwrapTreeData tree;
 
-               if (target_eval != NULL) {
+               if (BKE_shrinkwrap_init_tree(&tree, target_eval, 
scon->shrinkType, scon->shrinkMode, do_track_normal)) {
                        BLI_space_transform_from_matrices(&transform, 
cob->matrix, ct->tar->obmat);
 
                        switch (scon->shrinkType) {
@@ -3437,19 +3442,10 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
                                        nearest.index = -1;
                                        nearest.dist_sq = FLT_MAX;
 
-                                       if (scon->shrinkType == 
MOD_SHRINKWRAP_NEAREST_VERTEX)
-                                               
BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_VERTS, 2);
-                                       else
-                                               
BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_LOOPTRI, 2);
-
-                                       if (treeData.tree == NULL) {
-                                               fail = true;
-                                               break;
-                                       }
-
                                        BLI_space_transform_apply(&transform, 
co);
 
-                                       BLI_bvhtree_find_nearest(treeData.tree, 
co, &nearest, treeData.nearest_callback, &treeData);
+                                       BVHTreeFromMesh *treeData = 
&tree.treeData;
+                                       
BLI_bvhtree_find_nearest(treeData->tree, co, &nearest, 
treeData->nearest_callback, treeData);
 
                                        if (nearest.index < 0) {
                                                fail = true;
@@ -3457,7 +3453,13 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
                                        }
 
                                        if (scon->shrinkType == 
MOD_SHRINKWRAP_NEAREST_SURFACE) {
-                                               
BKE_shrinkwrap_snap_point_to_surface(scon->shrinkMode, nearest.co, nearest.no, 
scon->dist, co, co);
+                                               if (do_track_normal) {
+                                                       track_normal = true;
+                                                       
BKE_shrinkwrap_compute_smooth_normal(&tree, NULL, nearest.index, nearest.co, 
nearest.no, track_no);
+                                                       
BLI_space_transform_invert_normal(&transform, track_no);
+                                               }
+
+                                               
BKE_shrinkwrap_snap_point_to_surface(&tree, NULL, scon->shrinkMode, 
nearest.index, nearest.co, nearest.no, scon->dist, co, co);
                                        }
                                        else {
                                                const float dist = len_v3v3(co, 
nearest.co);
@@ -3504,16 +3506,9 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
                                                break;
                                        }
 
-                                       BKE_bvhtree_from_mesh_get(&treeData, 
target_eval, BVHTREE_FROM_LOOPTRI, 4);
-                                       if (treeData.tree == NULL) {
-                                               fail = true;
-                                               break;
-                                       }
-
                                        char cull_mode = scon->flag & 
CON_SHRINKWRAP_PROJECT_CULL_MASK;
 
-                                       
BKE_shrinkwrap_project_normal(cull_mode, co, no, 0.0f, &transform, 
treeData.tree,
-                                                                     &hit, 
treeData.raycast_callback, &treeData);
+                                       
BKE_shrinkwrap_project_normal(cull_mode, co, no, 0.0f, &transform, &tree, &hit);
 
                                        if (scon->flag & 
CON_SHRINKWRAP_PROJECT_OPPOSITE) {
                                                float inv_no[3];
@@ -3523,8 +3518,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
                                                        cull_mode ^= 
CON_SHRINKWRAP_PROJECT_CULL_MASK;
                                                }
 
-                                               
BKE_shrinkwrap_project_normal(cull_mode, co, inv_no, 0.0f, &transform, 
treeData.tree,
-                                                                             
&hit, treeData.raycast_callback, &treeData);
+                                               
BKE_shrinkwrap_project_normal(cull_mode, co, inv_no, 0.0f, &transform, &tree, 
&hit);
                                        }
 
                                        if (hit.index < 0) {
@@ -3532,12 +3526,17 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
                                                break;
                                        }
 
-                                       
BKE_shrinkwrap_snap_point_to_surface(scon->shrinkMode, hit.co, hit.no, 
scon->dist, co, co);
+                                       if (do_track_normal) {
+                                               track_normal = true;
+                                               
BKE_shrinkwrap_compute_smooth_normal(&tree, &transform, hit.index, hit.co, 
hit.no, track_no);
+                                       }
+
+                                       
BKE_shrinkwrap_snap_point_to_surface(&tree, &transform, scon->shrinkMode, 
hit.index, hit.co, hit.no, scon->dist, co, co);
                                        break;
                                }
                        }
 
-                       free_bvhtree_from_mesh(&treeData);
+                       BKE_shrinkwrap_free_tree(&tree);
 
                        if (fail == true) {
                                /* Don't move the point */
@@ -3547,6 +3546,11 @@ static void shrinkwrap_get_tarmat(struct Depsgraph 
*depsgraph, bConstraint *con,
                        /* co is in local object coordinates, change it to 
global and update target position */
                        mul_m4_v3(cob->matrix, co);
                        copy_v3_v3(ct->matrix[3], co);
+
+                       if (track_normal) {
+                               mul_mat3_m4_v3(cob->matrix, track_no);
+                               damptrack_do_transform(ct->matrix, track_no, 
scon->trackAxis);
+                       }
                }
        }
 }
@@ -3557,7 +3561,7 @@ static void shrinkwrap_evaluate(bConstraint *UNUSED(con), 
bConstraintOb *cob, Li
 
        /* only evaluate if there is a target */
        if (VALID_CONS_TARGET(ct)) {
-               copy_v3_v3(cob->matrix[3], ct->matrix[3]);
+               copy_m4_m4(cob->matrix, ct->matrix);
        }
 }
 
@@ -3631,7 +3635,22 @@ static void damptrack_evaluate(bConstraint *con, 
bConstraintOb *cob, ListBase *t
        bConstraintTarget *ct = targets->first;
 
        if (VALID_CONS_TARGET(ct)) {
-               float obvec[3], tarvec[3], obloc[3];
+               float tarvec[3];
+
+               /* find the (unit) direction vector going from the owner to the 
target */
+               sub_v3_v3v3(tarvec, ct->matrix[3], cob->matrix[3]);
+
+               damptrack_do_transform(cob->matrix, tarvec, data->trackflag);
+       }
+}
+
+static void damptrack_do_transform(float matrix[4][4], const float 
tarvec_in[3], int track_axis)
+{
+       /* find the (unit) direction vector going from the owner to the target 
*/
+       float tarvec[3];
+
+       if (normalize_v3_v3(tarvec, tarvec_in) != 0.0f) {
+               float obvec[3], obloc

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to