73 this->top_is_point = this->radius_top == 0.0f;
74 this->bottom_is_point = this->radius_bottom == 0.0f;
76 this->bottom_has_center_vert = this->bottom_is_point ||
79 this->tot_quad_rings = this->calculate_total_quad_rings();
80 this->tot_edge_rings = this->calculate_total_edge_rings();
81 this->tot_verts = this->calculate_total_verts();
82 this->tot_edges = this->calculate_total_edges();
83 this->tot_corners = this->calculate_total_corners();
86 this->first_ring_verts_start = this->top_has_center_vert ? 1 :
first_vert;
87 this->last_vert = this->tot_verts - 1;
90 this->first_ring_edges_start = this->top_has_center_vert ? this->
circle_segments : 0;
91 this->last_ring_edges_start = this->first_ring_edges_start +
92 this->tot_quad_rings * this->circle_segments * 2;
94 this->last_edge = this->tot_edges - 1;
96 this->top_faces_start = 0;
97 if (!this->top_is_point) {
103 this->top_faces_len = 0;
107 if (this->top_is_point && this->bottom_is_point) {
108 this->side_faces_len = 0;
114 if (!this->bottom_is_point) {
116 this->bottom_faces_len += this->bottom_has_center_vert ?
circle_segments : 0;
120 this->bottom_faces_len = 0;
122 this->bottom_faces_start = this->side_faces_start + this->
side_faces_len;
124 this->tot_faces = this->top_faces_len + this->side_faces_len + this->
bottom_faces_len;
128 int calculate_total_quad_rings();
129 int calculate_total_edge_rings();
130 int calculate_total_verts();
131 int calculate_total_edges();
132 int calculate_total_corners();
135int ConeConfig::calculate_total_quad_rings()
156int ConeConfig::calculate_total_edge_rings()
177int ConeConfig::calculate_total_verts()
206int ConeConfig::calculate_total_edges()
226int ConeConfig::calculate_total_corners()
232 int corner_total = 0;
259 circle[i].x = std::cos(angle);
260 circle[i].y = std::sin(angle);
261 angle += angle_delta;
268 positions[vert_index++] = {0.0f, 0.0f, config.
height};
275 const float top_fill_radius = top_fill_radius_delta * (i + 1);
277 const float x = circle[j].x * top_fill_radius;
278 const float y = circle[j].y * top_fill_radius;
279 positions[vert_index++] = {
x,
y, config.
height};
289 const float ring_radius = config.
radius_top + (side_radius_delta * (i + 1));
290 const float ring_height = config.
height - (height_delta * (i + 1));
292 const float x = circle[j].x * ring_radius;
293 const float y = circle[j].y * ring_radius;
294 positions[vert_index++] = {
x,
y, ring_height};
302 const float bottom_fill_radius = config.
radius_bottom - (i * bottom_fill_radius_delta);
304 const float x = circle[j].x * bottom_fill_radius;
305 const float y = circle[j].y * bottom_fill_radius;
306 positions[vert_index++] = {
x,
y, -config.
height};
313 positions[vert_index++] = {0.0f, 0.0f, -config.
height};
324 int2 &edge = edges[edge_index++];
333 const int next_ring_vert_start = this_ring_vert_start + config.
circle_segments;
336 int2 &edge = edges[edge_index++];
337 edge[0] = this_ring_vert_start + j;
346 int2 &edge = edges[edge_index++];
347 edge[0] = this_ring_vert_start + j;
348 edge[1] = next_ring_vert_start + j;
355 int2 &edge = edges[edge_index++];
367 int rings_face_start = 0;
368 int rings_loop_start = 0;
376 const int top_center_vert = 0;
377 const int top_fan_edges_start = 0;
380 const int loop_start = i * 3;
387 corner_edges[loop_start + 1] = top_fan_edges_start + ((i + 1) % config.
circle_segments);
389 corner_verts[loop_start + 2] = top_center_vert;
390 corner_edges[loop_start + 2] = top_fan_edges_start + i;
394 rings_face_start = 1;
407 face_sizes.
slice(rings_face_start, ring_faces_num).
fill(4);
409 const int this_ring_loop_start = rings_loop_start + i * config.
circle_segments * 4;
411 const int next_ring_vert_start = this_ring_vert_start + config.
circle_segments;
415 const int next_ring_edges_start = this_ring_edges_start + (2 * config.
circle_segments);
416 const int ring_connections_start = this_ring_edges_start + config.
circle_segments;
419 const int loop_start = this_ring_loop_start + j * 4;
421 corner_verts[loop_start + 0] = this_ring_vert_start + j;
422 corner_edges[loop_start + 0] = ring_connections_start + j;
424 corner_verts[loop_start + 1] = next_ring_vert_start + j;
425 corner_edges[loop_start + 1] = next_ring_edges_start + j;
427 corner_verts[loop_start + 2] = next_ring_vert_start + ((j + 1) % config.
circle_segments);
428 corner_edges[loop_start + 2] = ring_connections_start + ((j + 1) % config.
circle_segments);
430 corner_verts[loop_start + 3] = this_ring_vert_start + ((j + 1) % config.
circle_segments);
431 corner_edges[loop_start + 3] = this_ring_edges_start + j;
435 const int bottom_face_start = rings_face_start + ring_faces_num;
436 const int bottom_loop_start = rings_loop_start + ring_faces_num * 4;
443 const int loop_start = bottom_loop_start + i * 3;
448 corner_verts[loop_start + 1] = config.
last_vert;
462 corner_verts[bottom_loop_start + i] = config.
last_vert - i;
473 if (attribute_outputs.
top_id) {
506 if (attribute_outputs.
side_id) {
535 circle[i].x = std::cos(angle) * 0.225f;
536 circle[i].y = std::sin(angle) * 0.225f;
537 angle += angle_delta;
544 const float2 center_left(0.25f, 0.25f);
553 uvs[loop_index++] = radius_factor_delta * circle[i] + center_left;
554 uvs[loop_index++] = radius_factor_delta * circle[(i + 1) % config.
circle_segments] +
556 uvs[loop_index++] = center_left;
562 uvs[loop_index++] = radius_factor_delta * circle[i] + center_left;
566 for (
const int i :
IndexRange(1, left_circle_segment_count - 1)) {
567 const float inner_radius_factor = i * radius_factor_delta;
568 const float outer_radius_factor = (i + 1) * radius_factor_delta;
570 uvs[loop_index++] = inner_radius_factor * circle[j] + center_left;
571 uvs[loop_index++] = outer_radius_factor * circle[j] + center_left;
572 uvs[loop_index++] = outer_radius_factor * circle[(j + 1) % config.
circle_segments] +
574 uvs[loop_index++] = inner_radius_factor * circle[(j + 1) % config.
circle_segments] +
584 const float y_delta = (1.0f - bottom) /
float(config.
side_segments);
588 uvs[loop_index++] =
float2(j * x_delta, i * y_delta + bottom);
589 uvs[loop_index++] =
float2(j * x_delta, (i + 1) * y_delta + bottom);
590 uvs[loop_index++] =
float2((j + 1) * x_delta, (i + 1) * y_delta + bottom);
591 uvs[loop_index++] =
float2((j + 1) * x_delta, i * y_delta + bottom);
598 const float2 center_right(0.75f, 0.25f);
606 for (
const int i :
IndexRange(right_circle_segment_count - 1)) {
607 const float outer_radius_factor = 1.0f - i * radius_factor_delta;
608 const float inner_radius_factor = 1.0f - (i + 1) * radius_factor_delta;
610 uvs[loop_index++] = outer_radius_factor * circle[j] + center_right;
611 uvs[loop_index++] = inner_radius_factor * circle[j] + center_right;
612 uvs[loop_index++] = inner_radius_factor * circle[(j + 1) % config.
circle_segments] +
614 uvs[loop_index++] = outer_radius_factor * circle[(j + 1) % config.
circle_segments] +
622 uvs[loop_index++] = radius_factor_delta * circle[i] + center_right;
623 uvs[loop_index++] = center_right;
624 uvs[loop_index++] = radius_factor_delta * circle[(i + 1) % config.
circle_segments] +
632 uvs[loop_index++] = radius_factor_delta * circle[config.
circle_segments - 1 - i] +
645 mesh->vert_positions_for_write().first() =
float3(0);
656 const float radius_bottom,
658 const int circle_segments,
659 const int side_segments,
660 const int fill_segments,
665 radius_top, radius_bottom, depth, circle_segments, side_segments, fill_segments, fill_type);
670 if (config.
height == 0.0f) {
675 const float3 delta(0.0f, 0.0f, z_delta);
698 mesh->tag_loose_verts_none();
699 mesh->tag_loose_edges_none();
700 mesh->tag_overlapping_none();
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr void fill(const T &value) const
constexpr T & first() const
constexpr MutableSpan take_front(const int64_t n) const
draw_view in_light_buf[] float
void mesh_smooth_set(Mesh &mesh, bool use_smooth, bool keep_sharp_edges=false)
static Bounds< float3 > calculate_bounds_cylinder(const ConeConfig &config)
static void calculate_cone_uvs(const ConeConfig &config, Mesh *mesh, const StringRef uv_map_id)
Mesh * create_cylinder_or_cone_mesh(float radius_top, float radius_bottom, float depth, int circle_segments, int side_segments, int fill_segments, ConeFillType fill_type, ConeAttributeOutputs &attribute_outputs)
static Mesh * create_vertex_mesh()
static void calculate_cone_faces(const ConeConfig &config, MutableSpan< int > corner_verts, MutableSpan< int > corner_edges, MutableSpan< int > face_sizes)
Bounds< float3 > calculate_bounds_radial_primitive(float radius_top, float radius_bottom, int segments, float height)
Mesh * create_line_mesh(float3 start, float3 delta, int count)
static void calculate_cone_edges(const ConeConfig &config, MutableSpan< int2 > edges)
static void calculate_selection_outputs(const ConeConfig &config, const ConeAttributeOutputs &attribute_outputs, bke::MutableAttributeAccessor attributes)
static void calculate_cone_verts(const ConeConfig &config, MutableSpan< float3 > positions)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
VecBase< float, 2 > float2
VecBase< float, 3 > float3
MutableVArraySpan< T > span
std::optional< std::string > side_id
std::optional< std::string > top_id
std::optional< std::string > uv_map_id
std::optional< std::string > bottom_id
bool bottom_has_center_vert
int first_ring_verts_start
int last_ring_verts_start
int last_ring_edges_start
int first_ring_edges_start
ConeConfig(float radius_top, float radius_bottom, float depth, int circle_segments, int side_segments, int fill_segments, ConeFillType fill_type)