Subdiv: Fix/Workaround for surface partial derivatives

Both partial derivatives were evaluated to 0 for a special vertex on
Suzanne model: this is happening on a vertex where two adjacent faces
with 2 common edges are connected (in the nose of Suzanne).

This was breaking multires in this point since tangent matrix is all
zeroes, and hence no displacement can be applied in that vertex.
This commit is contained in:
Sergey Sharybin 2020-03-03 11:51:29 +01:00
parent b454a12233
commit 582205c134
1 changed files with 22 additions and 0 deletions

View File

@ -176,6 +176,28 @@ void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv,
float r_dPdv[3])
{
subdiv->evaluator->evaluateLimit(subdiv->evaluator, ptex_face_index, u, v, r_P, r_dPdu, r_dPdv);
/* NOTE: In a very rare occasions derivatives are evaluated to zeros. This happens, for example,
* in single vertex on Suzannne's nose (where two quads have 2 common edges).
*
* This makes tangent space displacement (such as multires) impossible to be used in those
* vertices, so those needs to be addressed in one way or another.
*
* Simplest thing to do: step inside of the face a little bit, where there is known patch at
* which there must be proper derivatives. This might break continuity of normals, but is better
* that giving totally unusable derivatives. */
if (r_dPdu != NULL && r_dPdv != NULL) {
if (is_zero_v3(r_dPdu) || is_zero_v3(r_dPdv)) {
subdiv->evaluator->evaluateLimit(subdiv->evaluator,
ptex_face_index,
u * 0.999f + 0.0005f,
v * 0.999f + 0.0005f,
r_P,
r_dPdu,
r_dPdv);
}
}
}
void BKE_subdiv_eval_limit_point_and_normal(Subdiv *subdiv,