Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMattias Fredriksson <Osares>2021-08-06 02:34:32 +0300
committerHans Goudey <h.goudey@me.com>2021-08-06 02:34:32 +0300
commitbc0d55e724a27fba61a93cc95f2cc48e205e1cd8 (patch)
tree1dcd4c1db63c7590c53da8dfe752ede0d07b27dd /source
parent263fa406cd2bc1aefe410fe735c22967ee052e22 (diff)
Fix: Avoid floating point error in some mesh primitive nodes
Some mesh primitives created using geometry nodes use loops to create vertices and accumulates positions/angles in FP variables. This allows rounding errors to accumulate and can introduce significant errors. To minimize changes from original implementation, variables allowing errors to accumulate are replaced by: delta * index. Affected Mesh Primitives nodes are Line, Grid, Cylinder, Circle, Cone, and UV-Sphere. Differential Revision: https://developer.blender.org/D12136
Diffstat (limited to 'source')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc14
5 files changed, 20 insertions, 27 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
index 96c6f073ab3..131f9548b40 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
@@ -126,11 +126,11 @@ static Mesh *create_circle_mesh(const float radius,
MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly};
- float angle = 0.0f;
- const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
- for (MVert &vert : verts) {
- copy_v3_v3(vert.co, float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f));
- angle += angle_delta;
+ /* Assign vertex coordinates. */
+ const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num));
+ for (const int i : IndexRange(verts_num)) {
+ const float angle = i * angle_delta;
+ copy_v3_v3(verts[i].co, float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f));
}
if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
copy_v3_v3(verts.last().co, float3(0));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index 790a518e584..b834f5e2fa0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@ -318,9 +318,9 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
/* Calculate vertex positions. */
const int top_verts_start = 0;
const int bottom_verts_start = top_verts_start + (!top_is_point ? verts_num : 1);
- float angle = 0.0f;
- const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
+ const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num));
for (const int i : IndexRange(verts_num)) {
+ const float angle = i * angle_delta;
const float x = std::cos(angle);
const float y = std::sin(angle);
if (!top_is_point) {
@@ -330,7 +330,6 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
copy_v3_v3(verts[bottom_verts_start + i].co,
float3(x * radius_bottom, y * radius_bottom, -height));
}
- angle += angle_delta;
}
if (top_is_point) {
copy_v3_v3(verts[top_verts_start].co, float3(0.0f, 0.0f, height));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
index 7a97ae8e318..410290c79ee 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
@@ -79,19 +79,17 @@ static Mesh *create_grid_mesh(const int verts_x,
MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly};
{
- const float dx = size_x / edges_x;
- const float dy = size_y / edges_y;
- float x = -size_x * 0.5;
+ const float dx = edges_x == 0 ? 0.0f : size_x / edges_x;
+ const float dy = edges_y == 0 ? 0.0f : size_y / edges_y;
+ const float x_shift = edges_x / 2.0f;
+ const float y_shift = edges_y / 2.0f;
for (const int x_index : IndexRange(verts_x)) {
- float y = -size_y * 0.5;
for (const int y_index : IndexRange(verts_y)) {
const int vert_index = x_index * verts_y + y_index;
- verts[vert_index].co[0] = x;
- verts[vert_index].co[1] = y;
+ verts[vert_index].co[0] = (x_index - x_shift) * dx;
+ verts[vert_index].co[1] = (y_index - y_shift) * dy;
verts[vert_index].co[2] = 0.0f;
- y += dy;
}
- x += dx;
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
index a193c05daa1..2e6d8ca34c8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
@@ -118,11 +118,9 @@ static Mesh *create_line_mesh(const float3 start, const float3 delta, const int
short normal[3];
normal_float_to_short_v3(normal, delta.normalized());
- float3 co = start;
for (const int i : verts.index_range()) {
- copy_v3_v3(verts[i].co, co);
+ copy_v3_v3(verts[i].co, start + delta * i);
copy_v3_v3_short(verts[i].no, normal);
- co += delta;
}
fill_edge_data(edges);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
index fe456dc4564..affba602234 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
@@ -69,26 +69,24 @@ static void calculate_sphere_vertex_data(MutableSpan<MVert> verts,
const int rings)
{
const float delta_theta = M_PI / rings;
- const float delta_phi = (2 * M_PI) / segments;
+ const float delta_phi = (2.0f * M_PI) / segments;
copy_v3_v3(verts[0].co, float3(0.0f, 0.0f, radius));
normal_float_to_short_v3(verts[0].no, float3(0.0f, 0.0f, 1.0f));
int vert_index = 1;
- float theta = delta_theta;
- for (const int UNUSED(ring) : IndexRange(rings - 1)) {
- float phi = 0.0f;
- const float z = cosf(theta);
- for (const int UNUSED(segment) : IndexRange(segments)) {
+ for (const int ring : IndexRange(1, rings - 1)) {
+ const float theta = ring * delta_theta;
+ const float z = std::cos(theta);
+ for (const int segment : IndexRange(1, segments)) {
+ const float phi = segment * delta_phi;
const float sin_theta = std::sin(theta);
const float x = sin_theta * std::cos(phi);
const float y = sin_theta * std::sin(phi);
copy_v3_v3(verts[vert_index].co, float3(x, y, z) * radius);
normal_float_to_short_v3(verts[vert_index].no, float3(x, y, z));
- phi += delta_phi;
vert_index++;
}
- theta += delta_theta;
}
copy_v3_v3(verts.last().co, float3(0.0f, 0.0f, -radius));