[Bf-blender-cvs] [f73bef57d9f] geometry-nodes-mesh-primitives: Add UVs to sphere primitive

Hans Goudey noreply at git.blender.org
Mon Mar 15 22:35:02 CET 2021


Commit: f73bef57d9f12844ac455469a638b4fde22f4260
Author: Hans Goudey
Date:   Mon Mar 15 15:34:15 2021 -0400
Branches: geometry-nodes-mesh-primitives
https://developer.blender.org/rBf73bef57d9f12844ac455469a638b4fde22f4260

Add UVs to sphere primitive

===================================================================

M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc

===================================================================

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



More information about the Bf-blender-cvs mailing list