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
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2021-03-15 22:34:15 +0300
committerHans Goudey <h.goudey@me.com>2021-03-15 22:34:15 +0300
commitf73bef57d9f12844ac455469a638b4fde22f4260 (patch)
tree43730bbc82803ee88cc1a026720adeec659a9d65
parentc97183258f41c7507b41410e0023a585f2e74c4f (diff)
Add UVs to sphere primitive
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc55
1 files changed, 48 insertions, 7 deletions
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 5f12d28b6ce..33af67f8d60 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
@@ -168,7 +168,7 @@ static void calculate_sphere_faces(MutableSpan<MLoop> loops,
int ring_vert_index_start = 1;
int ring_edge_index_start = segments;
- for (const int UNUSED(ring) : IndexRange(rings - 2)) {
+ for (const int UNUSED(ring) : IndexRange(1, rings - 2)) {
const int next_ring_vert_index_start = ring_vert_index_start + segments;
const int next_ring_edge_index_start = ring_edge_index_start + segments * 2;
const int ring_vertical_edge_index_start = ring_edge_index_start + segments;
@@ -185,10 +185,10 @@ static void calculate_sphere_faces(MutableSpan<MLoop> loops,
loop_b.v = next_ring_vert_index_start + segment;
loop_b.e = next_ring_edge_index_start + segment;
MLoop &loop_c = loops[loop_index++];
- loop_c.v = next_ring_vert_index_start + ((segment + 1) % segments);
- loop_c.e = ring_vertical_edge_index_start + ((segment + 1) % segments);
+ loop_c.v = next_ring_vert_index_start + (segment + 1) % segments;
+ loop_c.e = ring_vertical_edge_index_start + (segment + 1) % segments;
MLoop &loop_d = loops[loop_index++];
- loop_d.v = ring_vert_index_start + ((segment + 1) % segments);
+ loop_d.v = ring_vert_index_start + (segment + 1) % segments;
loop_d.e = ring_edge_index_start + segment;
}
ring_vert_index_start += segments;
@@ -207,7 +207,7 @@ static void calculate_sphere_faces(MutableSpan<MLoop> loops,
MLoop &loop_a = loops[loop_index++];
loop_a.v = last_vert_index;
- loop_a.e = bottom_edge_fan_start + ((segment + 1) % segments);
+ loop_a.e = bottom_edge_fan_start + (segment + 1) % segments;
MLoop &loop_b = loops[loop_index++];
loop_b.v = last_vert_ring_start + (segment + 1) % segments;
loop_b.e = last_edge_ring_start + segment;
@@ -217,6 +217,43 @@ static void calculate_sphere_faces(MutableSpan<MLoop> loops,
}
}
+static void calculate_uv_attribute(MeshComponent &mesh_component,
+ const float segments,
+ const float rings)
+{
+ OutputAttributePtr uv_attribute = mesh_component.attribute_try_get_for_output(
+ "uv", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr);
+ MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>();
+
+ int loop_index = 0;
+ const float dy = 1.0f / rings;
+
+ for (const int i_segment : IndexRange(segments)) {
+ const float segment = static_cast<float>(i_segment);
+ uvs[loop_index++] = float2((segment + 0.5f) / segments, 0.0f);
+ uvs[loop_index++] = float2((segment + 1.0f) / segments, dy);
+ uvs[loop_index++] = float2(segment / segments, dy);
+ }
+
+ for (const int i_ring : IndexRange(1, rings - 2)) {
+ const float ring = static_cast<float>(i_ring);
+ for (const int i_segment : IndexRange(segments)) {
+ const float segment = static_cast<float>(i_segment);
+ uvs[loop_index++] = float2(segment / segments, ring / rings);
+ uvs[loop_index++] = float2((segment + 1.0f) / segments, ring / rings);
+ uvs[loop_index++] = float2((segment + 1.0f) / segments, (ring + 1.0f) / rings);
+ uvs[loop_index++] = float2(segment / segments, (ring + 1.0f) / rings);
+ }
+ }
+
+ for (const int i_segment : IndexRange(segments)) {
+ const float segment = static_cast<float>(i_segment);
+ uvs[loop_index++] = float2((segment + 0.5f) / segments, 1.0f);
+ uvs[loop_index++] = float2((segment + 1.0f) / segments, 1.0f - dy);
+ uvs[loop_index++] = float2(segment / segments, 1.0f - dy);
+ }
+}
+
static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const int rings)
{
Mesh *mesh = BKE_mesh_new_nomain(sphere_vert_total(segments, rings),
@@ -254,11 +291,15 @@ static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
const float3 rotation = params.extract_input<float3>("Rotation");
Mesh *mesh = create_uv_sphere_mesh(radius, segments_num, rings_num);
- BLI_assert(BKE_mesh_is_valid(mesh));
transform_mesh(mesh, location, rotation, float3(1));
- params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
+ GeometrySet result_set = GeometrySet::create_with_mesh(mesh);
+
+ calculate_uv_attribute(
+ result_set.get_component_for_write<MeshComponent>(), segments_num, rings_num);
+
+ params.set_output("Geometry", result_set);
}
} // namespace blender::nodes