Page MenuHome

Shrink-Wrap Constraint: Align to Normal (Option)
Closed, ResolvedPublic


Benefits: The ability to orient along the surface, so objects can be made to follow a surface without manually rotating.

Description: Currently the shrink-wrap constraint lets you snap one object onto the surface of another.
Aligning to normal would rotate the object as well, so it would be aligned to the geometry that its snapped to.
This should be a factor from 0 to 1 where 0.0 is not aligned and `1.0 is completely aligned.


  • Investigate good methods of defining an 'UP' axis, the direction defined by the original and snapped location may work well, or it may be necessary to support XYZ axis options for the user to specific what is up, (this may need some feedback from riggers).
  • For situations where a mesh will move across a surface, we will want to be able to (optionally) interpolate the vertex normals, so the object rotates smoothly as it moves across the mesh. This isn't essential for the initial quick-hack, however it would be worth investigating (we should be able to supported it, but will take some more work).

Event Timeline

Brian Leman (Bleman) claimed this task.

Am I ok to pick this task up please?

Hi @Brian Leman (Bleman)! I recently made a video demo of what my revision accomplishes. I added a link to the video in my revision summary: ( (
I hope it's helpful to you as you work on it! Cheers~

Thanks for replying Masado Ishi. The video is really helpful thank you. :-)
I intend to work on this task within the next week.
i am going to be away from my computer for a few days but I will keep this post updated with any progress I make.
I am just preparing to download the blender source code and get setup with it so I can start the task.

Hi. I would like to pick up this task if it is not being worked on. @Masado Ishii (starintheuniverse) can you please elaborate what is it that exactly needs to be done here. I'm having some trouble understanding.

@Swarnadeep Mandal (doublegamer26): I didn't author the task, so at best I can explain my interpretation of what Campbell wrote. Do you have a specific question I might be able to help with? Also can I assume you are good with 3D math, and that you have also looked at the revision I submitted in Aug 2016?

I wonder how @Brian Leman (Bleman) is doing?

If you want to pick up where I left off, a possible first step would be to adapt the code I wrote to ensure it works with the newest version of Blender. My code revision was based on version 2.77. Blender has advanced by several versions since then.

Good luck!

@Masado Ishii (starintheuniverse) I am a very new developer and hence, I am mostly looking for a direction in which I should proceed. I am well versed with 3d maths so that's not an issue. I did have a look at your revision.
Also, how do I replicate the simulation for my testing?

@Swarnadeep Mandal (doublegamer26) Very good, that's great. (Forewarning--I am also a new developer. This was the first task I submitted a revision for, and I have not been too active since then. Also note that I never received feedback on what I submitted. So again, my guess is little better than yours.) Here are my suggested steps, depending where you are starting from:

  1. Make sure you can build Blender from source. ( Also make sure you can efficiently search through the massive code base for names of functions that are not explained well in Blender's documentation.
  2. To test your code as you write, I would recommend making a simpler scene, such as a sphere-surface and a stick-person. However, for you to replicate my video, I'll attach the blend file I made for it.This blend file includes a configuration for the Align-to-Normal settings in the Shrinkwrap constraint, though of course that setting will not even appear in your Blender until you change Blender's code and rebuild.
  3. Look up the files that are modified in my revision, and make the corresponding modifications. The constraint.c file contains the workings of the constraint algorithms. The "DNA" and "RNA" have to do with defining Blender's data model and serialization. The .py script in bl_ui creates the settings in the UI panel. (I realize my inline comments are a bit cryptic. Let me know if sending a copy of my geometric analysis would be helpful.)
    1. (Alternative to 3. which may or may not work) You could try to apply my revision using patch/diff, which are standard Unix utilities. ( If you go to D2154: Shrink-Wrap Constraint: Align to Normal (Option) -- iteration 1, then look on the right hand side of the page, there is a link to "Download Raw Diff"; the .diff file should be compatible with the patch/diff method. However, due to version differences (at the very least, line numbers will have likely changed), I can't say whether this will work.
  4. Now, finally, what needs to be done: Figure out how to get the vertex normal when the user has forced us into case MOD_SHRINKWRAP_NEAREST_VERTEX. Notice my comment /* XXX target mesh normal is not available from nearest when bvh tree made from verts. */ Finding out what a BVH tree is, and what kind of information is given by bvhtree_from_mesh_verts() or bvhtree_from_mesh_looptri(), was a tedious task. It involved probing the depths of Blender. Unfortunately I remember only what I made notes of; see below.
  5. Plan how to extend the function to optionally interpolate over surface/vertex normals. Forward thinking here may change how you solve the above problem. For example, you may want to extract information about neighboring vertices/faces for interpolation. Conversely, the locations of neighboring vertices may help you manually calculate the current vertex normal as well. If you can knock out two birds with one stone, that's great.

Best of luck~

Notes on BLI_bvhtree_find_nearest (in hopes of getting access to precomputed normals) (M. Ishii, 2016-08-15)

  • object_get_derived_final (in blenkernel/intern/DerivedMesh.c) returns either
    • ob->derivedFinal; or
    • ob->data->edit_btmesh->derivedFinal;
  • BLI_bvhtree_find_nearest calculates the projection of co onto each of the kdop axes, then invokes a dfs algorithm; utilizes data structure BVHNearestData. Returns an index (for a node?), with side effect on nearest.
  • dfs_find_nearest_dfs recursively runs down the bvh tree, selecting children by a distance calculation involving the above mentioned projection. In the recursive base case, data->callback is invoked with userdata, node->index, and fields inside data (co and nearest). If there is not a non-NULL callback, then nearest.index, nearest.dist_sq, and are updated.
  • When shrinkwrap_get_tarmat invokes BLI_bvhtree_find_nearest, the user data is treedata, and the supplied callback is treedata.nearest_callback. These objects will have been prepared by a call to bvhtree_from_mesh_verts or a call to bvhtree_from_mesh_looptri.
  • bvhtree_from_mesh_verts (in blenkernel/intern/bvhutils.c) sets up a NULL nearest_callback; while bvhtree_from_mesh_looptri sets up a callback called mesh_looptri_nearest_point.
  • bvhtree_from_mesh_looptri supplies normals using a geometry function called normal_tri_v3 (See blenlib/intern/math_geom.c).
    • Presumably normal_tri_v3 calculates the normal of the plane determined by three points.
  • Conclusion: bvhtree_from_mesh_verts does not collect normals; there is no surface.

Probably not. It now certainly does what I was asking for when Campbell created this task.

Aaron Carlisle (Blendify) closed this task as Resolved.Tue, Sep 3, 4:47 PM