Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| else if (!bottom_is_point && fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { | else if (!bottom_is_point && fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { | ||||
| corner_total += circle_segments; | corner_total += circle_segments; | ||||
| } | } | ||||
| return corner_total; | return corner_total; | ||||
| } | } | ||||
| static void calculate_cone_verts(const ConeConfig &config, MutableSpan<MVert> verts) | static void calculate_cone_verts(const ConeConfig &config, MutableSpan<float3> positions) | ||||
| { | { | ||||
| Array<float2> circle(config.circle_segments); | Array<float2> circle(config.circle_segments); | ||||
| const float angle_delta = 2.0f * (M_PI / float(config.circle_segments)); | const float angle_delta = 2.0f * (M_PI / float(config.circle_segments)); | ||||
| float angle = 0.0f; | float angle = 0.0f; | ||||
| for (const int i : IndexRange(config.circle_segments)) { | for (const int i : IndexRange(config.circle_segments)) { | ||||
| circle[i].x = std::cos(angle); | circle[i].x = std::cos(angle); | ||||
| circle[i].y = std::sin(angle); | circle[i].y = std::sin(angle); | ||||
| angle += angle_delta; | angle += angle_delta; | ||||
| } | } | ||||
| int vert_index = 0; | int vert_index = 0; | ||||
| /* Top cone tip or triangle fan center. */ | /* Top cone tip or triangle fan center. */ | ||||
| if (config.top_has_center_vert) { | if (config.top_has_center_vert) { | ||||
| copy_v3_fl3(verts[vert_index++].co, 0.0f, 0.0f, config.height); | positions[vert_index++] = {0.0f, 0.0f, config.height}; | ||||
| } | } | ||||
| /* Top fill including the outer edge of the fill. */ | /* Top fill including the outer edge of the fill. */ | ||||
| if (!config.top_is_point) { | if (!config.top_is_point) { | ||||
| const float top_fill_radius_delta = config.radius_top / float(config.fill_segments); | const float top_fill_radius_delta = config.radius_top / float(config.fill_segments); | ||||
| for (const int i : IndexRange(config.fill_segments)) { | for (const int i : IndexRange(config.fill_segments)) { | ||||
| const float top_fill_radius = top_fill_radius_delta * (i + 1); | const float top_fill_radius = top_fill_radius_delta * (i + 1); | ||||
| for (const int j : IndexRange(config.circle_segments)) { | for (const int j : IndexRange(config.circle_segments)) { | ||||
| const float x = circle[j].x * top_fill_radius; | const float x = circle[j].x * top_fill_radius; | ||||
| const float y = circle[j].y * top_fill_radius; | const float y = circle[j].y * top_fill_radius; | ||||
| copy_v3_fl3(verts[vert_index++].co, x, y, config.height); | positions[vert_index++] = {x, y, config.height}; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Rings along the side. */ | /* Rings along the side. */ | ||||
| const float side_radius_delta = (config.radius_bottom - config.radius_top) / | const float side_radius_delta = (config.radius_bottom - config.radius_top) / | ||||
| float(config.side_segments); | float(config.side_segments); | ||||
| const float height_delta = 2.0f * config.height / float(config.side_segments); | const float height_delta = 2.0f * config.height / float(config.side_segments); | ||||
| for (const int i : IndexRange(config.side_segments - 1)) { | for (const int i : IndexRange(config.side_segments - 1)) { | ||||
| const float ring_radius = config.radius_top + (side_radius_delta * (i + 1)); | const float ring_radius = config.radius_top + (side_radius_delta * (i + 1)); | ||||
| const float ring_height = config.height - (height_delta * (i + 1)); | const float ring_height = config.height - (height_delta * (i + 1)); | ||||
| for (const int j : IndexRange(config.circle_segments)) { | for (const int j : IndexRange(config.circle_segments)) { | ||||
| const float x = circle[j].x * ring_radius; | const float x = circle[j].x * ring_radius; | ||||
| const float y = circle[j].y * ring_radius; | const float y = circle[j].y * ring_radius; | ||||
| copy_v3_fl3(verts[vert_index++].co, x, y, ring_height); | positions[vert_index++] = {x, y, ring_height}; | ||||
| } | } | ||||
| } | } | ||||
| /* Bottom fill including the outer edge of the fill. */ | /* Bottom fill including the outer edge of the fill. */ | ||||
| if (!config.bottom_is_point) { | if (!config.bottom_is_point) { | ||||
| const float bottom_fill_radius_delta = config.radius_bottom / float(config.fill_segments); | const float bottom_fill_radius_delta = config.radius_bottom / float(config.fill_segments); | ||||
| for (const int i : IndexRange(config.fill_segments)) { | for (const int i : IndexRange(config.fill_segments)) { | ||||
| const float bottom_fill_radius = config.radius_bottom - (i * bottom_fill_radius_delta); | const float bottom_fill_radius = config.radius_bottom - (i * bottom_fill_radius_delta); | ||||
| for (const int j : IndexRange(config.circle_segments)) { | for (const int j : IndexRange(config.circle_segments)) { | ||||
| const float x = circle[j].x * bottom_fill_radius; | const float x = circle[j].x * bottom_fill_radius; | ||||
| const float y = circle[j].y * bottom_fill_radius; | const float y = circle[j].y * bottom_fill_radius; | ||||
| copy_v3_fl3(verts[vert_index++].co, x, y, -config.height); | positions[vert_index++] = {x, y, -config.height}; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Bottom cone tip or triangle fan center. */ | /* Bottom cone tip or triangle fan center. */ | ||||
| if (config.bottom_has_center_vert) { | if (config.bottom_has_center_vert) { | ||||
| copy_v3_fl3(verts[vert_index++].co, 0.0f, 0.0f, -config.height); | positions[vert_index++] = {0.0f, 0.0f, -config.height}; | ||||
| } | } | ||||
| } | } | ||||
| static void calculate_cone_edges(const ConeConfig &config, MutableSpan<MEdge> edges) | static void calculate_cone_edges(const ConeConfig &config, MutableSpan<MEdge> edges) | ||||
| { | { | ||||
| int edge_index = 0; | int edge_index = 0; | ||||
| /* Edges for top cone tip or triangle fan */ | /* Edges for top cone tip or triangle fan */ | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| uv_attribute.finish(); | uv_attribute.finish(); | ||||
| } | } | ||||
| static Mesh *create_vertex_mesh() | static Mesh *create_vertex_mesh() | ||||
| { | { | ||||
| /* Returns a mesh with a single vertex at the origin. */ | /* Returns a mesh with a single vertex at the origin. */ | ||||
| Mesh *mesh = BKE_mesh_new_nomain(1, 0, 0, 0, 0); | Mesh *mesh = BKE_mesh_new_nomain(1, 0, 0, 0, 0); | ||||
| copy_v3_fl3(mesh->verts_for_write().first().co, 0.0f, 0.0f, 0.0f); | mesh->vert_positions_for_write().first() = float3(0); | ||||
| return mesh; | return mesh; | ||||
| } | } | ||||
| Mesh *create_cylinder_or_cone_mesh(const float radius_top, | Mesh *create_cylinder_or_cone_mesh(const float radius_top, | ||||
| const float radius_bottom, | const float radius_bottom, | ||||
| const float depth, | const float depth, | ||||
| const int circle_segments, | const int circle_segments, | ||||
| const int side_segments, | const int side_segments, | ||||
| Show All 15 Lines | |||||
| const float3 delta(0.0f, 0.0f, z_delta); | const float3 delta(0.0f, 0.0f, z_delta); | ||||
| return create_line_mesh(start, delta, config.tot_verts); | return create_line_mesh(start, delta, config.tot_verts); | ||||
| } | } | ||||
| Mesh *mesh = BKE_mesh_new_nomain( | Mesh *mesh = BKE_mesh_new_nomain( | ||||
| config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces); | config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces); | ||||
| BKE_id_material_eval_ensure_default_slot(&mesh->id); | BKE_id_material_eval_ensure_default_slot(&mesh->id); | ||||
| MutableSpan<MVert> verts = mesh->verts_for_write(); | MutableSpan<float3> positions = mesh->vert_positions_for_write(); | ||||
| MutableSpan<MEdge> edges = mesh->edges_for_write(); | MutableSpan<MEdge> edges = mesh->edges_for_write(); | ||||
| MutableSpan<MPoly> polys = mesh->polys_for_write(); | MutableSpan<MPoly> polys = mesh->polys_for_write(); | ||||
| MutableSpan<MLoop> loops = mesh->loops_for_write(); | MutableSpan<MLoop> loops = mesh->loops_for_write(); | ||||
| calculate_cone_verts(config, verts); | calculate_cone_verts(config, positions); | ||||
| calculate_cone_edges(config, edges); | calculate_cone_edges(config, edges); | ||||
| calculate_cone_faces(config, loops, polys); | calculate_cone_faces(config, loops, polys); | ||||
| if (attribute_outputs.uv_map_id) { | if (attribute_outputs.uv_map_id) { | ||||
| calculate_cone_uvs(config, mesh, attribute_outputs.uv_map_id.get()); | calculate_cone_uvs(config, mesh, attribute_outputs.uv_map_id.get()); | ||||
| } | } | ||||
| calculate_selection_outputs(config, attribute_outputs, mesh->attributes_for_write()); | calculate_selection_outputs(config, attribute_outputs, mesh->attributes_for_write()); | ||||
| mesh->loose_edges_tag_none(); | mesh->loose_edges_tag_none(); | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||