77 this->top_is_point = this->radius_top == 0.0f;
78 this->bottom_is_point = this->radius_bottom == 0.0f;
79 this->top_has_center_vert = this->top_is_point ||
81 this->bottom_has_center_vert = this->bottom_is_point ||
84 this->tot_quad_rings = this->calculate_total_quad_rings();
85 this->tot_edge_rings = this->calculate_total_edge_rings();
86 this->tot_verts = this->calculate_total_verts();
87 this->tot_edges = this->calculate_total_edges();
88 this->tot_corners = this->calculate_total_corners();
91 this->first_ring_verts_start = this->top_has_center_vert ? 1 :
first_vert;
92 this->last_vert = this->tot_verts - 1;
95 this->first_ring_edges_start = this->top_has_center_vert ? this->
circle_segments : 0;
96 this->last_ring_edges_start = this->first_ring_edges_start +
97 this->tot_quad_rings * this->circle_segments * 2;
99 this->last_edge = this->tot_edges - 1;
101 this->top_faces_start = 0;
102 if (!this->top_is_point) {
104 this->top_faces_len += this->top_has_center_vert ?
circle_segments : 0;
108 this->top_faces_len = 0;
112 if (this->top_is_point && this->bottom_is_point) {
113 this->side_faces_len = 0;
119 if (!this->bottom_is_point) {
121 this->bottom_faces_len += this->bottom_has_center_vert ?
circle_segments : 0;
125 this->bottom_faces_len = 0;
127 this->bottom_faces_start = this->side_faces_start + this->
side_faces_len;
129 this->tot_faces = this->top_faces_len + this->side_faces_len + this->
bottom_faces_len;
133 int calculate_total_quad_rings();
134 int calculate_total_edge_rings();
135 int calculate_total_verts();
136 int calculate_total_edges();
137 int calculate_total_corners();
140 int ConeConfig::calculate_total_quad_rings()
161 int ConeConfig::calculate_total_edge_rings()
182 int ConeConfig::calculate_total_verts()
211 int ConeConfig::calculate_total_edges()
231 int ConeConfig::calculate_total_corners()
237 int corner_total = 0;
266 angle += angle_delta;
278 const float top_fill_radius_delta = config.
radius_top /
281 const float top_fill_radius = top_fill_radius_delta * (i + 1);
283 const float x = circle[j].x * top_fill_radius;
284 const float y = circle[j].y * top_fill_radius;
293 const float height_delta = 2.0f * config.
height /
static_cast<float>(config.
side_segments);
295 const float ring_radius = config.
radius_top + (side_radius_delta * (i + 1));
296 const float ring_height = config.
height - (height_delta * (i + 1));
298 const float x = circle[j].x * ring_radius;
299 const float y = circle[j].y * ring_radius;
306 const float bottom_fill_radius_delta = config.
radius_bottom /
309 const float bottom_fill_radius = config.
radius_bottom - (i * bottom_fill_radius_delta);
311 const float x = circle[j].x * bottom_fill_radius;
312 const float y = circle[j].y * bottom_fill_radius;
331 MEdge &edge = edges[edge_index++];
341 const int next_ring_vert_start = this_ring_vert_start + config.
circle_segments;
344 MEdge &edge = edges[edge_index++];
345 edge.v1 = this_ring_vert_start + j;
355 MEdge &edge = edges[edge_index++];
356 edge.v1 = this_ring_vert_start + j;
357 edge.v2 = next_ring_vert_start + j;
365 MEdge &edge = edges[edge_index++];
382 const int top_center_vert = 0;
383 const int top_fan_edges_start = 0;
386 MPoly &poly = polys[poly_index++];
390 MLoop &loop_a = loops[loop_index++];
393 MLoop &loop_b = loops[loop_index++];
396 MLoop &loop_c = loops[loop_index++];
397 loop_c.
v = top_center_vert;
398 loop_c.
e = top_fan_edges_start + i;
403 MPoly &poly = polys[poly_index++];
407 MLoop &loop = loops[loop_index++];
418 const int next_ring_vert_start = this_ring_vert_start + config.
circle_segments;
422 const int next_ring_edges_start = this_ring_edges_start + (2 * config.
circle_segments);
423 const int ring_connections_start = this_ring_edges_start + config.
circle_segments;
426 MPoly &poly = polys[poly_index++];
430 MLoop &loop_a = loops[loop_index++];
431 loop_a.
v = this_ring_vert_start + j;
432 loop_a.
e = ring_connections_start + j;
433 MLoop &loop_b = loops[loop_index++];
434 loop_b.
v = next_ring_vert_start + j;
435 loop_b.
e = next_ring_edges_start + j;
436 MLoop &loop_c = loops[loop_index++];
439 MLoop &loop_d = loops[loop_index++];
441 loop_d.
e = this_ring_edges_start + j;
449 MPoly &poly = polys[poly_index++];
453 MLoop &loop_a = loops[loop_index++];
456 MLoop &loop_b = loops[loop_index++];
459 MLoop &loop_c = loops[loop_index++];
466 MPoly &poly = polys[poly_index++];
472 MLoop &loop = loops[loop_index++];
486 if (attribute_outputs.
top_id) {
520 if (attribute_outputs.
side_id) {
551 angle += angle_delta;
558 const float2 center_left(0.25f, 0.25f);
559 const float radius_factor_delta = 1.0f / (config.
top_is_point ?
568 uvs[loop_index++] = radius_factor_delta * circle[i] + center_left;
569 uvs[loop_index++] = radius_factor_delta * circle[(i + 1) % config.
circle_segments] +
571 uvs[loop_index++] = center_left;
577 uvs[loop_index++] = radius_factor_delta * circle[i] + center_left;
581 for (
const int i :
IndexRange(1, left_circle_segment_count - 1)) {
582 const float inner_radius_factor = i * radius_factor_delta;
583 const float outer_radius_factor = (i + 1) * radius_factor_delta;
585 uvs[loop_index++] = inner_radius_factor * circle[j] + center_left;
586 uvs[loop_index++] = outer_radius_factor * circle[j] + center_left;
587 uvs[loop_index++] = outer_radius_factor * circle[(j + 1) % config.
circle_segments] +
589 uvs[loop_index++] = inner_radius_factor * circle[(j + 1) % config.
circle_segments] +
598 const float x_delta = 1.0f /
static_cast<float>(config.
circle_segments);
603 uvs[loop_index++] =
float2(j * x_delta, i * y_delta +
bottom);
604 uvs[loop_index++] =
float2(j * x_delta, (i + 1) * y_delta +
bottom);
605 uvs[loop_index++] =
float2((j + 1) * x_delta, (i + 1) * y_delta +
bottom);
606 uvs[loop_index++] =
float2((j + 1) * x_delta, i * y_delta +
bottom);
613 const float2 center_right(0.75f, 0.25f);
621 for (
const int i :
IndexRange(right_circle_segment_count - 1)) {
622 const float outer_radius_factor = 1.0f - i * radius_factor_delta;
623 const float inner_radius_factor = 1.0f - (i + 1) * radius_factor_delta;
625 uvs[loop_index++] = outer_radius_factor * circle[j] + center_right;
626 uvs[loop_index++] = inner_radius_factor * circle[j] + center_right;
627 uvs[loop_index++] = inner_radius_factor * circle[(j + 1) % config.
circle_segments] +
629 uvs[loop_index++] = outer_radius_factor * circle[(j + 1) % config.
circle_segments] +
637 uvs[loop_index++] = radius_factor_delta * circle[i] + center_right;
638 uvs[loop_index++] = center_right;
639 uvs[loop_index++] = radius_factor_delta * circle[(i + 1) % config.
circle_segments] +
647 uvs[loop_index++] = radius_factor_delta * circle[config.
circle_segments - 1 - i] +
665 const float radius_bottom,
667 const int circle_segments,
668 const int side_segments,
669 const int fill_segments,
674 radius_top, radius_bottom, depth, circle_segments, side_segments, fill_segments, fill_type);
679 if (config.
height == 0.0f) {
684 const float3 delta(0.0f, 0.0f, z_delta);
718 .
description(
N_(
"Number of points on the circle at the top and bottom"));
723 .
description(
N_(
"The number of edges running vertically along the side of the cone"));
728 .
description(
N_(
"Number of concentric rings used to fill the round face"));
732 .description(
N_(
"Radius of the top circle of the cone"));
755 node->storage = node_storage;
774 uiItemR(layout,
ptr,
"fill_type", 0,
nullptr, ICON_NONE);
782 const int circle_segments =
params.extract_input<
int>(
"Vertices");
783 if (circle_segments < 3) {
785 params.set_default_remaining_outputs();
789 const int side_segments =
params.extract_input<
int>(
"Side Segments");
790 if (side_segments < 1) {
792 params.set_default_remaining_outputs();
797 const int fill_segments = no_fill ? 1 :
params.extract_input<
int>(
"Fill Segments");
798 if (fill_segments < 1) {
800 params.set_default_remaining_outputs();
804 const float radius_top =
params.extract_input<
float>(
"Radius Top");
805 const float radius_bottom =
params.extract_input<
float>(
"Radius Bottom");
806 const float depth =
params.extract_input<
float>(
"Depth");
809 if (
params.output_is_required(
"Top")) {
812 if (
params.output_is_required(
"Bottom")) {
815 if (
params.output_is_required(
"Side")) {
831 if (attribute_outputs.top_id) {
833 AnonymousAttributeFieldInput::Create<bool>(
834 std::move(attribute_outputs.top_id),
params.attribute_producer_name()));
836 if (attribute_outputs.bottom_id) {
839 AnonymousAttributeFieldInput::Create<bool>(std::move(attribute_outputs.bottom_id),
840 params.attribute_producer_name()));
842 if (attribute_outputs.side_id) {
844 AnonymousAttributeFieldInput::Create<bool>(
845 std::move(attribute_outputs.side_id),
params.attribute_producer_name()));
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(struct ID *id)
void BKE_mesh_translate(struct Mesh *me, const float offset[3], bool do_keys)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
#define NODE_STORAGE_FUNCS(StorageT)
#define GEO_NODE_MESH_PRIMITIVE_CONE
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
#define NODE_CLASS_GEOMETRY
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
void nodeRegisterType(struct bNodeType *ntype)
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
GeometryNodeMeshCircleFillType
@ GEO_NODE_MESH_CIRCLE_FILL_NGON
@ GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN
@ GEO_NODE_MESH_CIRCLE_FILL_NONE
_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
_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 bottom
in reality light always falls off quadratically Particle Info
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
GSpanAttributeWriter lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type)
StringRefNull description() const
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
MutableAttributeAccessor mesh_attributes_for_write(Mesh &mesh)
OwnedAnonymousAttributeID< true > StrongAnonymousAttributeID
static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_geo_exec(GeoNodeExecParams params)
static void node_update(bNodeTree *ntree, bNode *node)
static void calculate_cone_vertices(const MutableSpan< MVert > &verts, const ConeConfig &config)
Mesh * create_line_mesh(const float3 start, const float3 delta, int count)
static void calculate_cone_faces(const MutableSpan< MLoop > &loops, const MutableSpan< MPoly > &polys, const ConeConfig &config)
static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config)
static void calculate_cone_edges(const MutableSpan< MEdge > &edges, const ConeConfig &config)
static void calculate_selection_outputs(Mesh *mesh, const ConeConfig &config, ConeAttributeOutputs &attribute_outputs)
Mesh * create_cylinder_or_cone_mesh(float radius_top, float radius_bottom, float depth, int circle_segments, int side_segments, int fill_segments, GeometryNodeMeshCircleFillType fill_type, ConeAttributeOutputs &attribute_outputs)
static Mesh * create_vertex_mesh()
vec_base< float, 3 > float3
vec_base< float, 2 > float2
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
void register_node_type_geo_mesh_primitive_cone()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
void node_free_standard_storage(bNode *node)
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
struct bNodeSocket * next
NodeGeometryExecFunction geometry_node_execute
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
NodeDeclareFunction declare
MutableVArraySpan< T > span
StrongAnonymousAttributeID bottom_id
StrongAnonymousAttributeID side_id
StrongAnonymousAttributeID top_id
int first_ring_edges_start
int first_ring_verts_start
int last_ring_edges_start
bool bottom_has_center_vert
ConeConfig(float radius_top, float radius_bottom, float depth, int circle_segments, int side_segments, int fill_segments, GeometryNodeMeshCircleFillType fill_type)
int last_ring_verts_start
GeometryNodeMeshCircleFillType fill_type