Page MenuHome

Grid Fill is generating mesh that's inconsistent with selected edge loops
Closed, ResolvedPublic

Description

System Information
Ubuntu 13.10 with nVidia GeForce GT 630M

Blender Version
Broken: 2.70 36279af

Short description of error

After invoking grid fill on 2 parallel edge loops the generated mesh does not connect the two loops straightly but instead forms a distorted shape.

Exact steps for others to reproduce the error

  • Open the attached .blend file
  • Invoke grid fill with CTRL-F G

Comment

I've done my side of investigation. This behaviour can only be observed when the surface normal of the interpolated face is [0 0 -1].
It seems that the C function rotation_between_vecs_to_quat doesn't handle the degenerative case in which 2 vectors are parallel to each other correctly.

Event Timeline

Yan Shi (ian.shi) added a project: BF Blender.
Yan Shi (ian.shi) set Type to Bug.
Yan Shi (ian.shi) created this task.
Yan Shi (ian.shi) raised the priority of this task from to Needs Triage by Developer.

I can confirm that behaviour on my system. (Windows 7 Pro - Blender 2.70 - hash 2aff243

Starting from the edges already selected in the example file, the grid fill operation produces the incorrect result seen in the first image file "grid-fill extra 00.jpg"

Just out of curiousity, I ran the operation again, but using the other set of edges perpendicular to the first set. In this case grid fill worked as expected. Image "grid-fill extra 01.jpg"

Bastien Montagne (mont29) triaged this task as Confirmed, Medium priority.

@Yan Shi (ian.shi): thanks a lot for this investigation, saved me some time! :)

Here is a proposed code for rotation_between_vecs_to_quat(), which fixes the issue:

void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
{
	float axis[3];
	float angle;

	cross_v3_v3v3(axis, v1, v2);

	if (len_squared_v3(axis) < FLT_EPSILON) {
		if (dot_v3v3(v1, v2) < 0.0f) {
			/* Colinear but opposed vectors, 180 rotation... */
			float a2[3];
			ortho_basis_v3v3_v3(axis, a2, v1);
			axis_angle_to_quat(q, axis, (float)M_PI);
		}
		else {
			/* Same vectors, zero rotation... */
			unit_qt(q);
		}
	}
	else {
		angle = angle_normalized_v3v3(v1, v2);

		axis_angle_to_quat(q, axis, angle);
	}
}

@Bastien Montagne (mont29), nice fix, suggest replacing ortho_basis_v3v3_v3 with a simpler function though,