28 {
SOCK_INT,
N_(
"Segments"), 32, 0.0f, 0.0f, 0.0f, 3, 1024},
29 {
SOCK_INT,
N_(
"Rings"), 16, 0.0f, 0.0f, 0.0f, 2, 1024},
43 return segments * (rings - 1) + 2;
48 return segments * (rings * 2 - 1);
53 const int quad_corners = 4 * segments * (rings - 2);
54 const int tri_corners = 3 * segments * 2;
55 return quad_corners + tri_corners;
60 const int quads = segments * (rings - 2);
61 const int triangles = segments * 2;
62 return quads + triangles;
70 const float delta_theta =
M_PI / rings;
77 float theta = delta_theta;
80 const float z =
cosf(theta);
82 const float sin_theta =
std::sin(theta);
83 const float x = sin_theta *
std::cos(phi);
84 const float y = sin_theta *
std::sin(phi);
104 const int first_vert_ring_index_start = 1;
106 MEdge &edge = edges[edge_index++];
108 edge.
v2 = first_vert_ring_index_start +
segment;
112 int ring_vert_index_start = 1;
113 for (
const int ring :
IndexRange(rings - 1)) {
114 const int next_ring_vert_index_start = ring_vert_index_start + segments;
118 MEdge &edge = edges[edge_index++];
119 edge.
v1 = ring_vert_index_start +
segment;
120 edge.
v2 = ring_vert_index_start + ((
segment + 1) % segments);
125 if (ring < rings - 2) {
127 MEdge &edge = edges[edge_index++];
128 edge.
v1 = ring_vert_index_start +
segment;
129 edge.
v2 = next_ring_vert_index_start +
segment;
133 ring_vert_index_start += segments;
138 const int last_vert_ring_start = last_vert_index - segments;
140 MEdge &edge = edges[edge_index++];
141 edge.
v1 = last_vert_index;
142 edge.
v2 = last_vert_ring_start +
segment;
156 const int first_vert_ring_index_start = 1;
158 MPoly &poly = polys[poly_index++];
161 MLoop &loop_a = loops[loop_index++];
164 MLoop &loop_b = loops[loop_index++];
165 loop_b.
v = first_vert_ring_index_start +
segment;
167 MLoop &loop_c = loops[loop_index++];
168 loop_c.
v = first_vert_ring_index_start + (
segment + 1) % segments;
169 loop_c.
e = (
segment + 1) % segments;
172 int ring_vert_index_start = 1;
173 int ring_edge_index_start = segments;
175 const int next_ring_vert_index_start = ring_vert_index_start + segments;
176 const int next_ring_edge_index_start = ring_edge_index_start + segments * 2;
177 const int ring_vertical_edge_index_start = ring_edge_index_start + segments;
180 MPoly &poly = polys[poly_index++];
184 MLoop &loop_a = loops[loop_index++];
185 loop_a.
v = ring_vert_index_start +
segment;
186 loop_a.
e = ring_vertical_edge_index_start +
segment;
187 MLoop &loop_b = loops[loop_index++];
188 loop_b.
v = next_ring_vert_index_start +
segment;
189 loop_b.
e = next_ring_edge_index_start +
segment;
190 MLoop &loop_c = loops[loop_index++];
191 loop_c.
v = next_ring_vert_index_start + (
segment + 1) % segments;
192 loop_c.
e = ring_vertical_edge_index_start + (
segment + 1) % segments;
193 MLoop &loop_d = loops[loop_index++];
194 loop_d.v = ring_vert_index_start + (
segment + 1) % segments;
195 loop_d.e = ring_edge_index_start +
segment;
197 ring_vert_index_start += segments;
198 ring_edge_index_start += segments * 2;
202 const int last_edge_ring_start = segments * (rings - 2) * 2 + segments;
203 const int bottom_edge_fan_start = last_edge_ring_start + segments;
205 const int last_vert_ring_start = last_vert_index - segments;
207 MPoly &poly = polys[poly_index++];
211 MLoop &loop_a = loops[loop_index++];
212 loop_a.
v = last_vert_index;
213 loop_a.
e = bottom_edge_fan_start + (
segment + 1) % segments;
214 MLoop &loop_b = loops[loop_index++];
215 loop_b.v = last_vert_ring_start + (
segment + 1) % segments;
216 loop_b.e = last_edge_ring_start +
segment;
217 MLoop &loop_c = loops[loop_index++];
218 loop_c.
v = last_vert_ring_start +
segment;
219 loop_c.
e = bottom_edge_fan_start +
segment;
232 const float dy = 1.0f / rings;
234 for (
const int i_segment :
IndexRange(segments)) {
235 const float segment =
static_cast<float>(i_segment);
236 uvs[loop_index++] =
float2((
segment + 0.5f) / segments, 0.0f);
241 for (
const int i_ring :
IndexRange(1, rings - 2)) {
242 const float ring =
static_cast<float>(i_ring);
243 for (
const int i_segment :
IndexRange(segments)) {
244 const float segment =
static_cast<float>(i_segment);
245 uvs[loop_index++] =
float2(
segment / segments, ring / rings);
246 uvs[loop_index++] =
float2(
segment / segments, (ring + 1.0f) / rings);
247 uvs[loop_index++] =
float2((
segment + 1.0f) / segments, (ring + 1.0f) / rings);
248 uvs[loop_index++] =
float2((
segment + 1.0f) / segments, ring / rings);
252 for (
const int i_segment :
IndexRange(segments)) {
253 const float segment =
static_cast<float>(i_segment);
254 uvs[loop_index++] =
float2((
segment + 0.5f) / segments, 1.0f);
255 uvs[loop_index++] =
float2((
segment + 1.0f) / segments, 1.0f - dy);
289 const int segments_num =
params.extract_input<
int>(
"Segments");
290 const int rings_num =
params.extract_input<
int>(
"Rings");
291 if (segments_num < 3 || rings_num < 2) {
296 const float radius =
params.extract_input<
float>(
"Radius");
bool BKE_mesh_is_valid(struct Mesh *me)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_MESH_PRIMITIVE_UV_SPHERE
void nodeRegisterType(struct bNodeType *ntype)
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
OutputAttributePtr attribute_try_get_for_output(const blender::StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type, const void *default_value=nullptr)
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void apply_span_and_save()
fn::GMutableSpan get_span_for_write_only()
Segment< FEdge *, Vec3r > segment
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
static void calculate_sphere_vertex_data(MutableSpan< MVert > verts, const float radius, const int segments, const int rings)
static void calculate_sphere_edge_indices(MutableSpan< MEdge > edges, const int segments, const int rings)
static int sphere_edge_total(const int segments, const int rings)
static int sphere_face_total(const int segments, const int rings)
static void calculate_sphere_uvs(Mesh *mesh, const float segments, const float rings)
static Mesh * create_uv_sphere_mesh(const float radius, const int segments, const int rings)
static void calculate_sphere_faces(MutableSpan< MLoop > loops, MutableSpan< MPoly > polys, const int segments, const int rings)
static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
static int sphere_corner_total(const int segments, const int rings)
static int sphere_vert_total(const int segments, const int rings)
static bNodeSocketTemplate geo_node_mesh_primitive_uv_sphere_out[]
static bNodeSocketTemplate geo_node_mesh_primitive_uv_sphere_in[]
void register_node_type_geo_mesh_primitive_uv_sphere()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Compact definition of a node socket.
NodeGeometryExecFunction geometry_node_execute